C # - Как изменить качество PNG или глубину цвета - PullRequest
13 голосов
/ 10 марта 2010

Я должен написать программу, которая получает некоторые изображения PNG от пользователя, выполняет некоторые простые изменения, такие как вращение, и сохраняет их в файле JAR, чтобы он мог использовать изображения в качестве ресурсов. Проблема в том, что когда я открываю, скажем, изображение размером 80 КБ, а затем сохраняю его с помощью C #, я получаю изображение с тем же качеством, но на 130 КБ. И поскольку он должен находиться внутри jar-файла J2ME, мне действительно нужны меньшие размеры, по крайней мере, оригинальный размер. Я попробовал код ниже, но позже узнал, что он работает только для изображений в формате JPEG.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                int j = 0;
                for (j = 0; j < codecs.Length; j++)
                {
                    if (codecs[j].MimeType == "image/png") break;
                }
                EncoderParameter ratio = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 10L);
                EncoderParameters CodecParams = new EncoderParameters(1);
                CodecParams.Param[0] = ratio;

                Image im;
                im = pictureBox1.Image;
                im.Save(address , codecs[j], CodecParams);

Здесь изображение загружается в графическое окно:

private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string address = openFileDialog1.FileName;
                address.Replace("\\", "\\\\");
                Image im = Image.FromFile(address);
                pictureBox1.Image = im;
            }
        }

И это то место, где оно сохраняется без изменений:

private void generateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {

                ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                int j = 0;
                for (j = 0; j < codecs.Length; j++)
                {
                    if (codecs[j].MimeType == "image/png") break;
                }
                EncoderParameter ratio = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 10L);
                EncoderParameters CodecParams = new EncoderParameters(1);
                CodecParams.Param[0] = ratio;

                string address = folderBrowserDialog1.SelectedPath;
                address = address + "\\";
                address.Replace("\\", "\\\\");

                Image im;
                im = pictureBox1.Image;               
                im.Save(address + imageFileNames[1], codecs[j], CodecParams);

Примечание. ImageFileNames [] - это просто строковый массив, содержащий имена файлов, в которые должны быть сохранены изображения.

Любые идеи будут оценены и заранее спасибо.

Ответы [ 2 ]

12 голосов
/ 20 декабря 2011

Извините, что поднял старый вопрос, но сегодня я решал ту же проблему и нашел эту страницу в MSDN: "Список параметров и значений для всех кодировщиков" . Я надеюсь, что было бы полезно сослаться на это там.

Статья содержит пример программы, которая выводит EncoderParameter s, поддерживаемые стандартными кодировщиками изображений GDI +, а PNG-кодировщик не поддерживает параметры в соответствии с ним.

Я не уверен, что можно принять это как должное, или в какой-то будущей версии gdiplus.dll кодировщик PNG может получить больше поддержки, и поэтому предполагается, что он проверяет возможности кодера во время выполнения.

В любом случае применение некоторого явного преобразования к исходному изображению представляется более плодотворным подходом; Я еще не исследовал это.

11 голосов
/ 10 марта 2010

Я взял 4 разных PNG размером от 2 КБ до 2,6 МБ. Используя ваш код, я загружаю их и сохраняю. Я не изменяю изображение, поворачивая или переворачивая. Все 4 PNG при повторном сохранении имеют одинаковый размер.

Кроме того, я взял PNG размером 2,6 МБ, открыл его в Photoshop и сохранил две его копии: одну с чересстрочной разверткой (уменьшенной до 2,06 МБ), одну без чересстрочной (уменьшенную до 1,7 МБ). Затем я взял каждую те, проверили их через ваш код и сохранили их. Полученные размеры обоих вернулись к исходным 2,6 МБ.

Итак, я предполагаю, что исходные изображения были созданы с помощью программного обеспечения (например, Photoshop), и у этого программного обеспечения есть оптимизированный алгоритм сжатия, который он использует для спецификации PNG, которую не использует .NET.

Я перепутал EncoderParameter for Compression, но, похоже, это никак не отразилось.

...