locked
PNG-8 or PNG-24 RRS feed

  • Question

  • User1447931844 posted

    when saving an image using this code, does it gets saved uing png-8 or png-24?

    pic.Save(MemStream, ImageFormat.Png)

    and is there a way to encode for png-8 and png-24? 

     

     

     

    Monday, January 29, 2007 11:58 PM

All replies

  • User-1082998358 posted

    I've generated a PNG using the following code:

     

    Graphics g = this.CreateGraphics();
    
    Bitmap b = new Bitmap(this.Width, this.Height, g);
    b.Save("C:\\temp.png", System.Drawing.Imaging.ImageFormat.Png);
    b.Dispose();
      I saw that it was saved using a depth of 32 bit. As I can't find some resources on MSDN so you have to do the compression job by yourself.

     

    Tuesday, January 30, 2007 2:15 AM
  • User1447931844 posted
    thanks but i can do that already, but does anyone else seen any code to created a PNG-8?
    Tuesday, January 30, 2007 8:29 AM
  • User-1082998358 posted

    Ok, try the following code

     

    ImageCodecInfo iciPng = null;
    foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageDecoders())
    {
        if (ici.FilenameExtension.ToLower().Contains("png"))
        {
            iciPng = ici;
            break;
        }
    }
    
    EncoderParameters eps = new EncoderParameters(1);
    EncoderParameter ep = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8L);
    
    eps.Param[0] = ep;
    
    
    Bitmap b = new Bitmap(@"myimage.bmp");
    b.Save("C:\\test.png", iciPng, eps);
    b.Dispose();

      This won't work if your image has transparency, then only 32 bit are possible. You can use 4, 8, 24 and 32 bit.

    If this is no solution for you then try the FreeImage Library. This does the job for you: http://freeimage.sourceforge.net/

     

    Tuesday, January 30, 2007 12:43 PM
  • User1447931844 posted

    thank you so much for the answer but i guess my image has transparency, is there any way to eliminate the transparency before saving it so i can use the 8 bits?

     

    Tuesday, January 30, 2007 1:00 PM
  • User-1082998358 posted
    Maybe there is a better way, but you can convert it first into a graphics format which doesn't support transparency. After that you convert it to a 8bit PNG.
    Wednesday, January 31, 2007 3:51 AM
  • User1447931844 posted

    it looks like .net will always create png as 24 bits images i'll will try using a free lib to try creating 8bits png files

    thanks all for the responses

    Sunday, February 4, 2007 10:20 AM
  • User-1082998358 posted
    The FreeImage Library should do this for you.
    Tuesday, February 6, 2007 5:31 AM
  • User1221432301 posted

    I tried to use FreeImage but I can't build my project. It says that the .dll is missing.

     But I could save as any PNG format with the .NET 3.0 Framework, the code follows, the only problem that it is 10x slower than the "new System.Drawing.Bitmap().Save()" method

     

    DrawingVisual drawingVisual = new DrawingVisual();
    System.Windows.Media.Pen pen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Blue, 5);
    System.Windows.Point a = new System.Windows.Point(256, 0);
    System.Windows.Point b = new System.Windows.Point(0, 256);
    drawingVisual = new DrawingVisual();
    using (DrawingContext drawingContext = drawingVisual.RenderOpen())
    {
    	drawingContext.DrawLine(pen, a, b);
    };
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(256, 256, 96, 96, PixelFormats.Pbgra32);
    renderTargetBitmap.Render(drawingVisual);
    FormatConvertedBitmap fcb = new FormatConvertedBitmap(renderTargetBitmap, PixelFormats.Indexed8, BitmapPalettes.Halftone8Transparent, 0.5);
    PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
    pngBitmapEncoder.Interlace = PngInterlaceOption.Off;
    pngBitmapEncoder.Frames.Add(BitmapFrame.Create(fcb));
    using (Stream fileStream = File.Open("2.png", FileMode.Create))
    {
        pngBitmapEncoder.Save(fileStream);
    }
      
    Thursday, October 16, 2008 12:19 PM
  • User1221432301 posted

     I also wrote a faster code that uses both System.Drawing and System.Windows.Media. It behaves 3x times faster than the previous WPF-only solution

     

     

    Bitmap image = new Bitmap(256, 256);
    Graphics graphics = Graphics.FromImage(image);
    graphics.CompositingQuality = CompositingQuality.HighSpeed;
    graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
    graphics.SmoothingMode = SmoothingMode.HighSpeed;//.AntiAlias;
    System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Black, 5);
    pen.StartCap = LineCap.Round;
    pen.EndCap = LineCap.Round;
    System.Drawing.PointF a = new System.Drawing.PointF(0, 255);
    System.Drawing.PointF b = new System.Drawing.PointF(255, 0);
    graphics.DrawLine(pen, a, b);
    FormatConvertedBitmap fcb = new FormatConvertedBitmap(System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(image.GetHbitmap(System.Drawing.Color.Transparent), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(256, 256)), PixelFormats.Indexed8, BitmapPalettes.Halftone8Transparent, 0.5);
    PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
    pngBitmapEncoder.Interlace = PngInterlaceOption.Off;
    pngBitmapEncoder.Frames.Add(BitmapFrame.Create(fcb));
    using (Stream fileStream = File.Open("3.png", FileMode.Create))
    {
        pngBitmapEncoder.Save(fileStream);
    }
      
    Thursday, October 16, 2008 1:34 PM