2009-07-02 8 views
14

У меня есть цифровая камера пушки, и я установил ее для съемки с превосходным качеством, и она выводит файл .jpg размером 3 мегабайта. Если я загрузить его, как это в ASP.NET (это полезно, чтобы изменить это разрешение или точек на дюйм кадрирование или whaterver).NET Сохранение jpeg с тем же качеством, что и было загружено

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

и потом сохранить его снова, как это:

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

его выводит jpg, размер которого составляет всего 700 КБ. Потеря качества.

Я также попытался сохранить его как это:

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

где codecJpeg является

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

и encparams:

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

Таким образом, размер (и я подозреваю, что и качество), но я вношу качество вручную.

Я хочу спросить:

Есть ли способ, чтобы сохранить изображение с таким же качеством, как она была загружена без жесткого кодирования значения качества?

Спасибо заранее

ответ

5

Так это звучит, как вы знаете, как установить качество, вы на самом деле просто нужно знать, как принести качество от исходного изображения?

Я подозреваю, что Image.PropertyItems является вашим другом, если качество находится в метаданных для начала. (Я не знаю, есть ли даже стандартная шкала для качества в кодировщиках JPEG.)

EDIT: Я только что проверил, и в jpeg, который я загрузил, не было никаких меток для качества.

Один из вариантов может заключаться в том, чтобы определить, насколько большой файл должен иметь примерно одинаковое качество, а затем сохранить его несколько раз, выполняя двоичный поиск, чтобы выработать наиболее подходящее качество. Икки, но это может сработать.

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

+2

Установка PropertyItems и пересохраните приведет к потере качества, потому что изображение будет повторно закодированы. Подробнее читайте здесь: http://stackoverflow.com/questions/1038206/net-c-library-for-lossless-exif-rewriting – arbiter

+0

Да, я ценю, что он будет перекодирован - но я думаю, что имеет смысл перекодировать примерно с той же «потерей», что и оригинал, если хотите. Вы по-прежнему будете терять данные, но, вероятно, не огромную сумму. Также обратите внимание, что я не говорил о настройке * PropertyItems - я говорил о * извлечении *, чтобы узнать исходное качество, хотя у него, похоже, нет соответствующих данных. –

+0

Ну, существует элемент propertyitem для получения качества jpeg - PropertyTagJPEGQuality, но он указан как частный тег для Adobe Photoshop, поэтому я не знаю, что он заполнен камерой или нет. Во всяком случае, есть небольшое чувство сохранения jpeg с тем же значением качества jpeg, потому что потеря качества будет там. – arbiter

0

Читайте здесь, как сохранить изображение без повторного кодирования изображения: How-to: Re-encode a JPEG Image with Metadata.

Однако, если вы делаете обрезку или другие манипуляции с изображениями, это невозможно сделать без потери качества (хорошо технически можно делать потери без урожая, если вы работаете с границами, которые умножаются на 16, но AFAIK не может с библиотеками, доступными в .net).

0

Вы должны использовать дополнительные параметры, которые сообщают GDI + для определения цветовой схемы.

Например:

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