Я видел, что много людей пытается кодировать их собственные методы преобразования изображения. Это часто, кажется, очень сложно, и заканчивает тем, что использовало GDI + вызовы функции и управляло битами изображения. Это имеет меня задающийся вопросом, отсутствую ли я, что-то в простоте преобразования изображения.NET звонит при сохранении образа. Вот код, который я имею:
Bitmap tempBmp = new Bitmap("c:\temp\img.jpg");
Bitmap bmp = new Bitmap(tempBmp, 800, 600);
bmp.Save(c:\temp\img.bmp, //extension depends on format
ImageFormat.Bmp) //These are all the ImageFormats I allow conversion to within the program. Ignore the syntax for a second ;)
ImageFormat.Gif) //or
ImageFormat.Jpeg) //or
ImageFormat.Png) //or
ImageFormat.Tiff) //or
ImageFormat.Wmf) //or
ImageFormat.Bmp)//or
);
Это - все, что я делаю в своем преобразовании изображения. Просто установив местоположение того, где образ должен быть сохранен, и передача его тип ImageFormat. Я протестировал его лучшее, я могу, но я задаюсь вопросом, пропускаю ли я что-нибудь в этом простом преобразовании формата, или если это достаточно?
System.Drawing.Imaging
действительно дает вам дополнительный контроль над сжатием изображения, если вы передаете кодек JPEG и устанавливаете параметр кодировщика для качества, что по сути представляет собой процент удержания.
Вот функция, которую я использую с параметром «image / jpeg»
для получения кодека JPEG. (Это не связано со сжатием как таковым , но для перегрузок Image.Save
, которые принимают EncoderParameters
, требуется ImageCodecInfo
вместо ] ImageFormat
.)
// assumes an encoder for "image/jpeg" will be available.
public static ImageCodecInfo GetCodec( string mimeType )
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for( int i = 0; i < encoders.Length; i++ )
if( encoders[i].MimeType == mimeType )
return encoders[i];
return null;
}
Затем вы можете установить параметры кодировщика перед сохранением изображения.
EncoderParameters ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter( Encoder.Quality, percentRetention ); // 1-100
ep.Param[1] = new EncoderParameter( Encoder.ColorDepth, colorDepth ); // e.g. 24L
(Существуют и другие параметры кодера - см. Документацию.
Итак, сложите все вместе, и вы можете сказать
image.Save( outFile, GetCodec("image/jpeg"), ep );
(Я сохраняю кодек и параметры в статических значениях, поскольку они используются снова и снова , но я хотел упростить пример здесь.)
Надеюсь, это поможет!
РЕДАКТИРОВАТЬ: Если вы масштабируете изображения, у вас также есть некоторый контроль над качеством. Да, это очень «черный ящик», но я считаю, что он работает хорошо. Вот настройки «хорошо и медленно» (которые вам нужно установить перед вызовом DrawImage, но вы можете найти «быстрые и грязные» версии.
// good & slow
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
Я думаю, передавая формат изображения, .NET выполняет сжатие, связанное с ImageFormat, за вас.
Но когда дело доходит до сжатия графики, может быть гораздо больше (см. В качестве примера диалоговое окно «Сохранить как» в Photoshop или графических программах).
Например, JPEG - это просто стандарт ... и для большого количества веб-графики вы все равно можете уменьшить размер, размыв или убрав больше цветов без заметной потери качества.
Все зависит от вас, какие техники вы собираетесь использовать, или вас устраивает Стандарт.
То, что вы делаете, будет работать, но далеко не самым эффективным и не самым экономичным размером файлов.
Причина, по которой вы видите сложный код GDI при работе с изображениями, заключается в том, что нет разумной середины между использованием стандартных универсальных методов и даже самой скромной степенью тонкой настройки.
Взаимодействие .net <-> gdi граничит с черной магией, где много неясных ошибок. К счастью, в Google есть все, что нужно для навигации по этому минному полю.
(я нарисовал достаточно ужасную картину?; -))
Если серьезно, вы можете неплохо справиться с gdi interop, но это отнюдь не очевидная задача. Если вы готовы провести исследование и потратить время на устранение недостатков, вы можете получить хороший код.
В противном случае найдите библиотеку изображений, которая сделает большую часть этого за вас.