AskalotLearnalot Ответов: 1

Растровое изображение увеличивает размер tif после достижения определенной точки


Я использую растровое изображение для водяного знака файлов изображений tif после того, как он достигает номера файла 440, размер изображения увеличивается, что приводит к появлению небольшого текстового водяного знака. Мой метод предназначен для обработки большого количества файлов, он также проверяет, окрашено ли изображение или нет, и обрабатывает его соответствующим образом. Любые предложения о том, что я должен попробовать. Я не знаю, почему это происходит. первоначальный размер: 2480 x 3580
большой размер: 5250 x 7497

Что я уже пробовал:

public void waterMark(string euroPrefix, string resultedTifFolders, string waterMarkedTif)
        {

            using (Brush brush = new SolidBrush(Color.Black))
            {
                using (Font font = new Font("Arial", 50, GraphicsUnit.Pixel))
                {
                    using (Bitmap original_bitmap = new Bitmap(resultedTifFolders))
                    {
                        int compressionTagIndex = Array.IndexOf(original_bitmap.PropertyIdList, 0x103);
                        PropertyItem compressionTag = original_bitmap.PropertyItems[compressionTagIndex];
                        byte[] com = compressionTag.Value;
                        Encoder encoder = Encoder.Compression;
                        EncoderParameters myEncoderParameters = new EncoderParameters(1);
                        EncoderParameter myEncoderParameter = new EncoderParameter(encoder, (long)EncoderValue.CompressionCCITT4);
                        myEncoderParameters.Param[0] = myEncoderParameter;
                        ImageCodecInfo myImageCodecInfo;
                        myImageCodecInfo = GetEncoderInfo("image/tiff");
                        SizeF euroPrefixSize;
                        if (new[] { 5, 7 }.Contains(com[0]))

                        {
                            using (Graphics tempGraphics = Graphics.FromImage(original_bitmap))
                            {
                                euroPrefixSize = tempGraphics.MeasureString(euroPrefix, font);
                            }

                            using (Bitmap new_bitmap = new Bitmap(original_bitmap.Width, original_bitmap.Height + (int)euroPrefixSize.Height + 10))
                            {
                                new_bitmap.SetResolution(original_bitmap.HorizontalResolution,original_bitmap.VerticalResolution);
                                using (Graphics graphics = Graphics.FromImage(new_bitmap))
                                {

                                    graphics.FillRectangle(Brushes.White, 0, 0, original_bitmap.Width, original_bitmap.Height + 100);

                                    graphics.DrawImage(original_bitmap, 0, 0, original_bitmap.Width, original_bitmap.Height);

                                    Point position = new Point(original_bitmap.Width - ((int)euroPrefixSize.Width + 200), original_bitmap.Height + 5);

                                    graphics.DrawString(euroPrefix, font, brush, position);

                                    new_bitmap.Save(waterMarkedTif, /*ImageFormat.Tiff,*/ myImageCodecInfo, myEncoderParameters);


                                    new_bitmap.Save(waterMarkedTif, ImageFormat.Tiff);
                                }
                            }
                            return;
                        }
                        else
                        {

                            Bitmap tempBitmap = new Bitmap(original_bitmap.Width, original_bitmap.Height);

                            using (Graphics tempGraphics = Graphics.FromImage(tempBitmap))
                            {
                                euroPrefixSize = tempGraphics.MeasureString(euroPrefix, font);
                            }
                            tempBitmap = new Bitmap(original_bitmap.Width, original_bitmap.Height + (int)euroPrefixSize.Height + 10);

                            tempBitmap.SetResolution(original_bitmap.HorizontalResolution,original_bitmap.VerticalResolution);

                            using (Graphics graphics = Graphics.FromImage(tempBitmap))
                            {
                                graphics.FillRectangle(Brushes.White, 0, 0, original_bitmap.Width, original_bitmap.Height + 100);

                                graphics.DrawImage(original_bitmap, 0, 0, original_bitmap.Width, original_bitmap.Height);

                                Point position = new Point(original_bitmap.Width - ((int)euroPrefixSize.Width + 200), original_bitmap.Height + 5);

                                graphics.DrawString((euroPrefix), font, brush, position);

                                tempBitmap.Save(waterMarkedTif, ImageFormat.Tiff);
                            }
                        }
                    }
                }
            }
        }

Daniele Rota Nodari

Я бы проверил эффекты "SetResolution", в случае отсрочки его вызова или попытки избежать его.
Переменная myEncoderParameters-еще один кандидат.
В additon я бы переместил все вызовы "Save" из блоков "using (Graphics)" (это также позволило бы переместить SetResolution между использованием блока и сохранением вызова).

AskalotLearnalot

Спасибо, я займусь этим. Что касается использования и сохранения, то я сделал это таким образом, потому что GDI не хватает места, когда я редактирую большое количество файлов за один раз.

Daniele Rota Nodari

Да, как вы уже сделали, утилизация графических объектов важна для сокращения использования ресурсов, и "использование" - это простой способ обеспечить это.
Это еще одна причина, чтобы переместить "сохранить" из "использования", чтобы избавиться от графических объектов, как только они больше не нужны.
Вы можете переместить перед любым блоком "using" любую инструкцию, которая не взаимодействует с графическим объектом, выделенным этим "using"; это также может помочь в рефакторинге кода, переместив некоторый код в новые, специализированные методы (например: есть 2 блока "using(Graphics....", которые кажутся почти идентичными друг другу).
Последнее: using/Dispose отсутствуют для tempBitmap; обратите внимание на это, потому что этой переменной назначены два новых объекта Bitmap.

1 Ответов

Рейтинг:
11

OriginalGriff

Мы не можем точно сказать, не запустив ваш код на ваших данных - и у нас нет доступа ни к тому, ни к другому!

Так что все будет зависеть от тебя.
К счастью, у вас есть инструмент, который поможет вам выяснить, что происходит: отладчик. Если вы не знаете, как его использовать, то быстрый Google для "Visual Studio debugger" должен дать вам необходимую информацию.

Поместите точку останова в первую строку функции и запустите код через отладчик. Затем посмотрите на свой код и на свои данные и определите, что должно произойти вручную. Затем по одному шагу в каждой строке проверяйте, что то, что вы ожидали, произойдет именно так, как и произошло. Когда это не так, тогда у вас есть проблема, и вы можете вернуться назад (или запустить ее снова и посмотреть более внимательно), чтобы выяснить, почему.

Возможно, вы захотите добавить код, чтобы сделать точку останова, когда она терпит неудачу, проще - возможно, подсчет или проверка имени / размера файла, чтобы вы могли пройти через рабочую и неудачную.

Извините, но мы не можем сделать это за вас - пришло время вам освоить новый (и очень, очень полезный) навык: отладку!


AskalotLearnalot

пожалуйста, добавьте это в качестве комментария, как есть. Я знаю, как отлаживать, спасибо.

phil.o

Итак, мы должны знать, что вы уже пытались отладить? Что вы узнали из сеансов отладки, которые вы провели? Есть какая-нибудь полезная информация?

AskalotLearnalot

это было 0 ошибок и предупреждений

phil.o

Затем вы думаете, что знаете, что такое отладка, но это не так. Отладка не указывает вам на очевидные ошибки и предупреждения, она используется для того, чтобы исследовать кусок кода и узнайте, почему результат, который вы получаете, не то, что вы ожидаете.
Возвращаясь к вашей текущей проблеме, вы должны использовать отладку, чтобы найти причину увеличения размера; это означает установку точки останова в коде, запуск сеанса отладки и тщательное наблюдение за значениями ваших переменных и возвращаемыми значениями из функций. Как сказал вам ОГ, мы не можем сделать это за вас, потому что это расследование не может быть проведено без фактических данных.

OriginalGriff

Компиляторы не говорят вам об ошибках, они говорят вам о синтаксических ошибках: где вы написали код на немецком языке, а он ожидал английского. Предположим, ваш код - это инструкции по заправке кровати:
1) распространение лист над матрасом, так.
2) Залейте лист бензином.
3) зажгите спичку, бросьте на лист.
4) Подходит Пуховое Одеяло.
5) Добавьте подушки.

Это все английский язык, поэтому компилятор не заботится о том, что следование инструкциям сожжет дом дотла, это нормально.

Но когда вы запускаете код, вы обнаруживаете ошибку: вы не можете сказать, заправлена ли кровать, потому что ваш дом разрушен, и вы находитесь в больнице.

Отладчики позволяют вам шаг за шагом выполнять инструкции (среди прочего, и смотреть на то, что происходит: когда вы доберетесь до шага 3, Вы можете заметить, что вот-вот произойдет что-то серьезное, и посмотреть более внимательно, чтобы выяснить, почему.

Поэтому разбейте отладчик и используйте его, чтобы посмотреть, что делает ваш код во время выполнения: компилятор не скажет вам этого, только запуск кода. Отладчик - это инструмент, который делает просмотр происходящего намного проще. Погуглите его и посмотрите, что вы можете узнать.

AskalotLearnalot

Как я уже сказал, Я знаю, как отлаживать. Если бы я мог исправить эту проблему или иметь более подробную информацию, я бы не публиковал здесь. Хорошего дня.