Запазете изображение в съответния му формат в поток

Имам предизвикателство, което включва множество части, с повечето от които нямам проблем. Имам нужда от функция, която чете поток от изображения, автоматично го преоразмерява до определен размер, компресира изображението до определено ниво (ако е приложимо) и след това връща потока от изображения, но също така запазва оригиналния формат на изображението и запазва прозрачността (ако има всякакви.)

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

Това включва четене на оригиналния формат на изображението и този код изглежда работи:

// 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 за формата, но не и действителната стойност на enum:

    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