2009-07-02 9 views
14

Tengo una cámara digital de cañón y la configuré para tomar fotos con calidad superfina y se emite un archivo .jpg de 3 mega. Si lo cargo como este en ASP.NET (esto es útil para cambiar su ppp de resolución o recortarla o whaterver).NET Guardar jpeg con la misma calidad que se cargó

imgPicture = Image.FromFile(Config.WorkDirectory + this.TempPhotoName); 
bmpPicture = new Bitmap(imgPicture); 

y luego volver a guardarlo como esto:

bmpModified.Save(Config.WorkDirectory + this.TempPhotoName,System.Drawing.Imaging.ImageFormat.Jpeg); 

se produce un jpg que tiene un tamaño de solo 700KB. Hay una pérdida de calidad.

También probé el ahorro de esta manera:

bmpPicture.Save(Config.WorkDirectory + this.TempPhotoName, codecJpeg, encparams); 

donde codecJpeg es

ImageCodecInfo codecJpeg = this.getEncoderInfo("image/jpeg"); 


    private ImageCodecInfo getEncoderInfo(string mimeType) 
    { 
     // Get image codecs for all image formats 
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 

     // Find the correct image codec 
     for (int i = 0; i < codecs.Length; i++) 
      if (codecs[i].MimeType == mimeType) 
       return codecs[i]; 
     return null; 
    } 

y encparams:

EncoderParameters encparams = new EncoderParameters(1); 
encparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 97L); 

esta manera el tamaño (y sospecho que también la calidad) se mantiene, pero estoy ingresando la calidad a mano.

quiero preguntar:

¿Hay una manera de salvar la imagen con la misma calidad que estaba cargada y sin codificar el valor de la calidad?

gracias de antemano

Respuesta

5

por lo que suena como usted sabe cómo configurar la calidad, que realmente sólo tiene que saber cómo buscar a la calidad de la imagen original?

Sospecho que Image.PropertyItems es su amigo, si la calidad está en los metadatos para empezar. (No sé si hay incluso una escala estándar para la calidad dentro de los codificadores JPEG.)

EDITAR: Acabo de verificar, y un archivo JPEG que descargué no tenía ninguna etiqueta de calidad.

Una opción podría ser determinar qué tan grande debe ser el archivo para tener aproximadamente la misma calidad, y luego guardarlo varias veces, haciendo una búsqueda binaria para encontrar la calidad más adecuada. Icky, pero podría funcionar.

tengo la sospecha de que allí no es simplemente una manera de preservar la configuración de la calidad original, aunque no tengo muy buenas razones para que la sospecha ...

+2

Configuración PropertyItems y volver a guardar dará lugar a la pérdida de calidad, ya que se vuelven a codificar la imagen. Lea más aquí: http://stackoverflow.com/questions/1038206/net-c-library-for-lossless-exif-rewriting – arbiter

+0

Sí, aprecio que se vuelva a codificar, pero creo que tiene sentido vuelva a codificar en aproximadamente la misma "pérdida" que el original, si lo desea. Todavía vas a perder datos, pero probablemente no una gran cantidad. También tenga en cuenta que no estaba hablando de * setting * PropertyItems - Estaba hablando de * fetching * it para averiguar la calidad original, aunque parece que no tiene los datos relevantes. –

+0

Bueno, existe un elemento propertyitem para recuperar calidad jpeg - PropertyTagJPEGQuality, pero se indica como etiqueta privada para Adobe Photoshop, por lo que no sé si se llena con cámara o no. De todos modos hay una pequeña sensación de almacenar jpeg con el mismo valor de calidad jpeg, porque la pérdida de calidad estará allí. – arbiter

0

Lea aquí cómo ahorrar imagen sin recodificar imagen: How-to: Re-encode a JPEG Image with Metadata.

Sin embargo, si recorta u otra manipulación de imagen es imposible hacerlo sin pérdida de calidad (técnicamente es posible hacer cultivos sin pérdidas, si trabaja con límites que se multiplican de 16, pero AFAIK no puede hacerse con las bibliotecas disponibles en .net).

0

Debe usar los parámetros adicionales que indican a GDI + que debe detectar el esquema de color.

Por ejemplo:

using (var img = Image.FromStream(fileupload.InputStream, true,true)) 
{ 
    img.Save(fileOnDisk, ImageFormat.Jpeg); 
} 

using (var img = Image.FromFile("yourimage", true)) 
{ 
    img.Save(fileOnDisk, ImageFormat.Jpeg); 
} 
Cuestiones relacionadas