2010-04-20 2 views
5

Я видел, как многие люди пытаются закодировать свои собственные методы преобразования изображений. Это часто кажется очень сложным и заканчивается использованием вызовов функций GDI + и манипулированием битами изображения. Это заставило меня задуматься, не хватает ли я чего-то в простоте обращения к конверсии изображений .NET при сохранении изображения. Вот код, который у меня есть:Достаточно ли использовать преобразование .NET Image?

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. Я тестировал это как можно лучше, но мне интересно, не хватает ли чего-либо в этом простом преобразовании формата, или если этого достаточно?

ответ

5

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); 

(я храню кодек и параметры в статических значений, так как они используются снова и снова, но я хотел, чтобы упростить пример здесь .)

Надеюсь, что это поможет!

EDIT: Если вы масштабируете изображения, у вас также есть некоторый контроль над качеством. Да, это очень «черный ящик», но я считаю, что он работает хорошо. Вот «хорошие & медленные» настройки (которые вам необходимо установить перед вызовом DrawImage, но вы можете посмотреть на «быстрые & грязные» версии.

// good & slow 
graphics.SmoothingMode  = SmoothingMode.HighQuality; 
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 
graphics.CompositingQuality = CompositingQuality.HighQuality; 
+0

+1 ответ. Просто хотелось бы отметить, что SmoothingMode не влияет на масштабирование изображения, он влияет на примитивы draiwng как линии, эллипсы и т. д. –

0

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

Но когда дело доходит до Графического сжатия, может быть гораздо больше. (См. Пример Photoshop или Диалоговое окно Save-As Graphic-Programms).

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

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

0

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

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

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

(сделал я рисовать достаточно плачевное картину? ;-))

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^