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:"список параметров и значений для всех кодеров". Я надеюсь, что было бы полезно обратиться к нему там.
статья содержит пример программы, которая выводит EncoderParameter
s поддерживается фондовыми GDI + кодировщиками изображений, а png-кодировщик не поддерживает никаких параметров в соответствии с ним.
Я не уверен, что можно считать это само собой разумеющимся, или в некоторых будущая версия gdiplus.dll
кодировщик PNG может получить больше поддержки, и поэтому предполагается проверить возможности кодировщика во время выполнения.
в любом случае применение некоторого явного преобразования к исходному изображению кажется более плодотворным подходом; я еще не исследовал его.