Сохранить изображение в соответствующем формате в поток - PullRequest
3 голосов
/ 22 ноября 2011

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

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

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

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

1 Ответ

2 голосов
/ 08 июля 2013

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

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

EDIT

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

...