Загрузка изображения без потери качества - PullRequest
1 голос
/ 17 ноября 2011

У меня есть пользовательская галерея на сайте, и посетители могут загрузить некоторые изображения. После загрузки изображение должно быть изменено до некоторых предустановленных настроек. Кроме того, оригинальное изображение должно быть сохранено. Все отлично работает для png и bmp форматов изображений. Но если я загружаю gif формат или jpeg с преобладанием одного цвета, загруженное исходное изображение кажется сжатым.

Например:

Оригинал:
Original image

Загружено:
Uploaded image

Я тщательно искал в Google и нашел несколько примеров, как правильно загрузить изображение. В конце я написал следующий метод:

void UploadImagePreset(Image image, ImageFormat imgFormat, string imgPath)
{
    using (var uploadStream = imageUploader.CreateUploadStream(imagePath))
    {
        var newWidth = image.Width;
        var newHeight = image.Height;
        using (var outBitmap = new Bitmap(newWidth, newHeight))
        {
            using (var outGraph = Graphics.FromImage(outBitmap))
            {
                outGraph.CompositingQuality = CompositingQuality.HighQuality;
                outGraph.SmoothingMode = SmoothingMode.HighQuality;
                outGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
                outGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

                var imageRect = new Rectangle(0, 0, newWidth, newHeight);
                outGraph.DrawImage(image, imageRect);

                outBitmap.Save(uploadStream, imgFormat);
            }
        }
    }
}

Но это не помогло. Загруженное изображение было таким же, как описано выше. Я попытался указать качество изображения результатов следующим образом:

var encoderParameters = new EncoderParameters();
var encoderParameter = new EncoderParameter(Encoder.Quality, 100);
encoderParameters.Param[0] = encoderParameter;
var encoder = ImageCodecInfo.GetImageEncoders()
    .Where(e => e.FormatID == imgFormat.Guid)
    .FirstOrDefault();
outBitmap.Save(uploadStream, encoder, encoderParameters);

Это тоже не работает. Кроме того, при загрузке изображения в формате JPEG возникает исключение.

Можно ли загрузить изображение без сжатия или изменения размера? Я потратил несколько часов на решение этой проблемы и застрял на ней.

Ответы [ 2 ]

7 голосов
/ 17 ноября 2011

Вы передаете загруженное изображение через класс Image - это новое изображение, основанное на переданном входящем потоке.

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

Вы должны просто сохранить входящий поток непосредственно на диск - это приведет к точной копии исходного изображения.

Вот так (.NET 4.0):

using (var uploadStream = imageUploader.CreateUploadStream(imagePath))
{
   using(var fileStream = new FileStream(imgPath, FileMode.Create))
   {
       uploadStream.CopyTo(fileStream);
   }
}

Или (до .NET 4.0):

using (var uploadStream = imageUploader.CreateUploadStream(imagePath))
{
    using(var fileStream = new FileStream(imgPath, FileMode.Create))
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = uploadStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            fileStream.Write(buffer, 0, read);
        }
    }
}

Адаптировано с этот ответ .

1 голос
/ 17 ноября 2011

Я предлагаю использовать Image Codecs (Ваш второй пример) для сжатия изображений без потерь.

С небольшой модификацией кода я предлагаю вам попробовать это:

Bitmap bm = (Bitmap)Image.FromFile(filePath); 
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
ImageCodecInfo codecInfo = null; 
foreach (ImageCodecInfo codec in codecs)
{ 
    if (codec.MimeType == "image/jpeg") 
        codecInfo = codec; 
}
EncoderParameters ep = new EncoderParameters(); 
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100); 
bm.Save("C:\\quality" + x.ToString() + ".jpg", codecInfo, ep);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...