Speichern Sie ein Bild in seinem jeweiligen Format in einem Stream

  • Ich habe eine Herausforderung, die aus mehreren Teilen besteht, von denen die meisten keine Probleme haben. Ich brauche eine Funktion, die einen Bilddatenstrom liest, die Größe automatisch auf eine angegebene Größe ändert, das Bild auf ein bestimmtes Niveau komprimiert (falls zutreffend) und dann den Bilddatenstrom zurückgibt, aber auch das ursprüngliche Bildformat und die Transparenz (falls vorhanden) beibehalten any.)

    Hierbei handelt es sich um eine einfache Größenänderungsfunktion, mit der ich keine Probleme habe.

    Es geht um das Lesen des Originalbildes Format, und dieser Code scheint zu funktionieren:

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

    Beim Zurückgeben des Bild-Streams stecke ich fest. Ich kann einen Stream mit der Komprimierung zurückgeben, aber standardmäßig Jpeg. Ich sehe nicht, wo ich das Format angeben soll. Und wenn ich das Format durch zweimaliges Speichern des Bildes festlege, verliere ich die Transparenz.

    Ich denke, es gibt zwei Fragen:

    1) Wenn ich die Größe des Bildes ändern möchte, muss ich außerdem die Alphatransparenz einer PNG-Datei neu erstellen? 2) Wie kann ich im jeweiligen Format einen Speicher-Stream speichern und dabei die Transparenz beibehalten, wenn dies erforderlich ist?

    Hier ist mein kaputter Code!

     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();
     
    22 November 2011
    James
1 answer
  • Dies ist was ich benutze, obwohl ich nicht mit Transparenz getestet habe. Dadurch bleibt das Bild im ursprünglichen Format, ohne dass das Rohformat aktiviert wird. Der Grund für die Verwendung von jpeg ist wahrscheinlich, dass newImage.RawFormat als Guid für das Format zurückgegeben wird, nicht jedoch der tatsächliche Enumerationswert:

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

    BEARBEITEN

    Ich habe das gerade mit Transparenz auf einem PNG getestet und es hat es behalten. Ich werde das unter gut abschreiben (bis jetzt habe ich es nur für jpegs verwendet.)

    08 July 2013
    Mark Avenius