Достаточно ли использовать .NET Image Conversion? - PullRequest
5 голосов
/ 20 апреля 2010

Я видел много людей, пытающихся закодировать свои собственные методы преобразования изображений. Это часто кажется очень сложным и заканчивается использованием вызовов функций 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. Я проверил это как мог, но мне интересно, если я что-то упускаю в этом простом преобразовании формата, или этого достаточно?

Ответы [ 3 ]

5 голосов
/ 20 апреля 2010

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;
0 голосов
/ 20 апреля 2010

То, что вы делаете, будет работать, но это далеко не самый эффективный и не самый экономичный размер файла.

Причина, по которой вы видите сложный код GDI при работе с изображениями, заключается в том, что нет разумного среднего уровня между использованием стандартных методов «один размер подходит всем» и даже самой скромной степенью тонкой настройки.

Взаимодействие .net <-> gdi граничит с черной магией, где изобилуют непонятные ошибки. К счастью, в Google есть все, что вам нужно для навигации по этому минному полю.

(я нарисовал достаточно ужасную картину?; -))

Если серьезно, вы можете неплохо справиться с gdi interop, но это ни в коем случае не является очевидной задачей. Если вы готовы провести исследование и потратить время на разработку изломов, вы можете получить хороший код.

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

0 голосов
/ 20 апреля 2010

Я думаю, передав формат изображения .NET выполняет сжатие, связанное с форматом изображения, для вас.

Но когда дело доходит до графического сжатия, может быть гораздо больше этого (см. Пример в Photoshop или в диалоге сохранения графических программ).

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

Вам решать, какие методы вы будете использовать, или если вы хорошо справляетесь со Стандартом.

...