Сохранение изображения в соответствующем формате в поток

У меня есть задача, которая включает в себя несколько частей, с большинством из которых у меня нет проблем. Мне нужна функция, которая считывает поток изображения, автоматически изменяет его размер до указанного размера, сжимает изображение до определенного уровня (если применимо), а затем возвращает поток изображения, но также сохраняет исходный формат изображения и сохраняет прозрачность (если есть любой.)

Это включает в себя простую функцию изменения размера, с которой у меня нет проблем.

Он включает в себя чтение исходного формата изображения, и этот код работает:

// Detect image format
if (newImage.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
      //etc for other formats
}
//etc

Возврат потока изображений - это то, где я застрял. Я могу вернуть поток со сжатием, но по умолчанию это Jpeg. Я не вижу, где указать формат. И когда я указываю формат, дважды сохраняя изображение, я теряю прозрачность.

Я предполагаю, что есть два вопроса:

1) Если я изменю размер изображения, мне также нужно восстановить альфа-прозрачность в PNG? 2) Как я могу сохранить в поток памяти в соответствующем формате, сохраняя при этом прозрачность, когда это необходимо?

Вот мой сломанный код!

System.Drawing.Imaging.ImageCodecInfo[] Info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters Params = new System.Drawing.Imaging.EncoderParameters(1);
long ImgComp = 80;
Params.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ImgComp);

MemoryStream m_s = new MemoryStream();
// Detect image format
if (newImage.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
    newBMP.Save(m_s, ImageFormat.Jpeg);
}
else if (newImage.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
{
    newBMP.Save(m_s, ImageFormat.Png);
}

// Save the new graphic file to the server

newBMP.Save(m_s, Info[1], Params);
retArr = m_s.ToArray();

person Lucas    schedule 22.11.2011    source источник
comment
Это выглядит интересно в отношении потери прозрачности при изменении размера: изображение теряет прозрачность"> stackoverflow.com/questions/753968/   -  person Lucas    schedule 22.11.2011


Ответы (1)


Это то, что я использую, хотя я не тестировал прозрачность. Это сохраняет изображение в исходном формате без переключения на необработанный формат. Причина, по которой вы, вероятно, по умолчанию используете jpeg, заключается в том, что newImage.RawFormat возвращается как guid для формата, но не фактическое значение перечисления:

    using (Bitmap newBmp = new Bitmap(size.Width, size.Height))
    {
        using (Graphics canvas = Graphics.FromImage(newBmp))
        {
            canvas.SmoothingMode = SmoothingMode.HighQuality;
            canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
            canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
            canvas.DrawImage(newImage, new Rectangle(new Point(0, 0), size));
            using (var stream = new FileStream(newLocation, FileMode.Create))
            {
                // keep image in existing format
                var newFormat = newImage.RawFormat;
                var encoder = GetEncoder(newFormat);
                var parameters = new EncoderParameters(1);
                parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);

                newBmp.Save(stream, encoder, parameters);
                stream.Flush();
            }
        }
    }

ИЗМЕНИТЬ

Я только что проверил это с прозрачностью на png, и он сохранил ее. Я запишу это как полезно знать (до сих пор я использовал его только для jpeg).

person Mark Avenius    schedule 08.07.2013