2010-04-20 10 views
5

He visto a mucha gente tratar de codificar sus propias técnicas de conversión de imágenes. A menudo parece ser muy complicado y termina usando llamadas de función GDI + y manipulando bits de la imagen. Esto me hizo preguntarme si me falta algo en la simplicidad de la llamada de conversión de imagen de .NET cuando guardo una imagen. Aquí está el código que tengo:¿Está usando la Conversión de Imágenes .NET lo suficiente?

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

Esto es todo lo que estoy haciendo en mi conversión de imagen. Simplemente estableciendo la ubicación donde se debe guardar la imagen y pasándole un tipo de ImageFormat. Lo he probado lo mejor que puedo, pero me pregunto si me falta algo en esta conversión de formato simple, o si esto es suficiente.

Respuesta

5

System.Drawing.Imaging le da control adicional sobre la compresión de imagen si pasa el códec JPEG y establece el parámetro del codificador para Calidad, que es esencialmente retención de porcentaje.

Aquí hay una función que uso con el parámetro "image/jpeg" para obtener el códec JPEG. (Esto no está relacionado con la compresión per se, pero los Image.Save sobrecargas que aceptan EncoderParameters requiere ImageCodecInfo en lugar de 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; 
} 

entonces se puede establecer los parámetros del codificador antes de guardar la imagen.

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 

(Hay otros parámetros del codificador — consulte la documentación.

lo tanto, poner todo junto, y se puede decir

image.Save(outFile, GetCodec("image/jpeg"), ep); 

(almaceno el codec y los parámetros en los valores estáticos, ya que se utilizan una y otra vez, pero quería simplificar el ejemplo aquí .)

Espero que esto ayude!

EDITAR: Si está escalando las imágenes, también tiene cierto control sobre la calidad. Sí, es muy "caja negra", pero creo que funciona bien. Estos son los "buenos" & lentos ajustes (que usted necesita para configurar antes de llamar DrawImage, pero se pueden buscar los "sucios" & rápidas versiones.

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

+1 respuesta. Sólo quería señalar que SmoothingMode no afecta la escala de la imagen, afecta a las primitivas de draiwng como líneas, elipses y demás. –

0

Creo que al pasar el formato de imagen .NET realiza la compresión asociada con el ImageFormat por usted.

Pero cuando se trata de compresión gráfica, puede haber mucho más que eso (consulte el cuadro de diálogo Guardar/Como de Photoshop o Gráfico-Programas).

JPEG, por ejemplo, es solo un estándar ... y para muchos gráficos web aún puede reducir el tamaño borrando o quitando más colores sin una pérdida de calidad notable.

Depende de usted qué técnicas va a utilizar o si está de acuerdo con un estándar.

0

Lo que está haciendo funcionará pero no es de lejos el más eficiente ni produce el tamaño de archivo más económico.

La razón por la que ve el código GDI complejo cuando se trata de imágenes es que no hay un término medio razonable entre el uso de los métodos únicos para todos e incluso el más modesto de los ajustes.

.net < -> gdi interopera fronteras en magia negra donde abundan los errores oscuros. Por suerte, Google tiene todo lo que necesitas para navegar en este campo minado.

(hizo pinto una imagen lo suficientemente grave? ;-))

serio, que puede hacer bastante bien con GDI interoperabilidad pero de ninguna manera es una tarea obvia. Si estás dispuesto a investigar y te tomas el tiempo para resolver los problemas, puedes terminar con un buen código.

De lo contrario, encuentre una biblioteca de imágenes que hace la mayor parte de esto por usted.

Cuestiones relacionadas