C# - как изменить качество PNG или глубину цвета

Я должен написать программу, которая получает некоторые изображения PNG от пользователя, делает некоторые простые изменения, такие как вращение и сохраняет их внутри файла JAR, чтобы он мог использовать изображения в качестве ресурсов. Проблема в том, что когда я открываю, скажем, изображение 80kb, а затем сохраняю его с помощью C#, я получаю изображение с тем же качеством, но для пространства 130kb. И поскольку он должен войти в файл J2ME jar, мне действительно нужны более низкие размеры, по крайней мере, исходный размер. Я попробовал код ниже, но позже узнал, что он работает только для изображение 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 ответов


Я взял 4 разных PNGs, начиная от размеров от 2KB до 2.6 MB. Используя ваш код, я загружаю их и сохраняю. Я не изменяю изображение, поворачивая или переворачивая. Все 4 PNGs, при повторном сохранении, имеют точно такой же размер.

кроме того, я взял 2.6 MB PNG, открыл его в Photoshop и сохранил две его копии, одну чересстрочную (уменьшенную до 2.06 MB), одну не чересстрочную (уменьшенную до 1.7 MB).) Затем я взял каждый из них, прогнал их через ваш код и сохранил их. Этот результирующие размеры обоих вернулись к исходному 2.6 MB.

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

я возился с EncoderParameter для сжатия, но, похоже, не имеет никакого влияния.


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

статья содержит пример программы, которая выводит EncoderParameters поддерживается фондовыми GDI + кодировщиками изображений, а png-кодировщик не поддерживает никаких параметров в соответствии с ним.

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

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