Problem writing png (but no problem with jpeg or gif)

207 views
Skip to first unread message

Graham MacDonald

unread,
Dec 4, 2013, 6:58:24 PM12/4/13
to golan...@googlegroups.com
Hi

I've got some simple code to write out the same image in 3 different formats: png, jpeg and gif.  The image is correctly written for jpeg and gif, but I get a zero length file for the png.  Any idea why this would happen, or does it look like a bug?

Here's the code:

package main

import (
    "bufio"
    "fmt"
    "image"
    "image/color"
    "image/draw"
    "image/gif"
    "image/jpeg"
    "image/png"
    "os"
)

func main() {
    img := image.NewRGBA(image.Rect(0, 0, 640, 480))

    c := color.RGBA{255, 0, 0, 255}
    draw.Draw(img, image.Rect(10, 10, 100, 100), &image.Uniform{c}, image.ZP, draw.Src)

    if imgFilePng, err := os.Create("red.png"); err != nil {
        fmt.Println("Png error: ", err)
    } else {
        defer imgFilePng.Close()
        png.Encode(bufio.NewWriter(imgFilePng), img)
    }

    if imgFileGif, err := os.Create("red.gif"); err != nil {
        fmt.Println("Gif error: ", err)
    } else {
        defer imgFileGif.Close()
        gif.Encode(bufio.NewWriter(imgFileGif), img, &gif.Options{})
    }

    if imgFileJpeg, err := os.Create("red.jpeg"); err != nil {
        fmt.Println("Jpeg error: ", err)
    } else {
        defer imgFileJpeg.Close()
        jpeg.Encode(bufio.NewWriter(imgFileJpeg), img, &jpeg.Options{jpeg.DefaultQuality})
    }
}


Cheers,
Graham

Jesse McNelis

unread,
Dec 4, 2013, 7:02:28 PM12/4/13
to Graham MacDonald, golang-nuts
On Thu, Dec 5, 2013 at 10:58 AM, Graham MacDonald <grahamam...@gmail.com> wrote:
Hi

I've got some simple code to write out the same image in 3 different formats: png, jpeg and gif.  The image is correctly written for jpeg and gif, but I get a zero length file for the png.  Any idea why this would happen, or does it look like a bug?

The error returned from png.Encode() might point you in the right direction.




--
=====================
http://jessta.id.au

Graham MacDonald

unread,
Dec 4, 2013, 7:20:22 PM12/4/13
to golan...@googlegroups.com, Graham MacDonald, jes...@jessta.id.au
Thanks, but I don't get an error from png.Encode.  (I should have put the check in the given example, though I had it in an earlier version.)  Adding the check to this example shows the returned value from png.Encode is nil.

Jesse McNelis

unread,
Dec 4, 2013, 7:24:40 PM12/4/13
to Graham MacDonald, golang-nuts


On 05/12/2013 11:20 AM, "Graham MacDonald" <grahamam...@gmail.com> wrote:
>
> Thanks, but I don't get an error from png.Encode.  (I should have put the check in the given example, though I had it in an earlier version.)  Adding the check to this example shows the returned value from png.Encode is nil.
>

Ah, then perhaps the issue is that you're not flushing the bufio.Writer

Alex Skinner

unread,
Dec 4, 2013, 11:39:06 PM12/4/13
to golan...@googlegroups.com, Graham MacDonald, jes...@jessta.id.au
This is exactly it.  The png is not large enough to trigger the flush automatically.

Alex

Graham MacDonald

unread,
Dec 5, 2013, 2:20:55 AM12/5/13
to golan...@googlegroups.com
Yes, that's it.  If I flush the writer, the png is written.  Curiously though, with this example, the png has a white background, while the jpeg and gif both have black backgrounds.

Thanks,
Graham

Carlos Castillo

unread,
Dec 5, 2013, 3:26:00 AM12/5/13
to golan...@googlegroups.com
For the record, this is a bad way to use bufio.Writer. You should always flush the buffer before closing the underlying writer or you will be missing data. I suspect that your "working" JPEG and GIF images from your original posted code are incomplete files too (just somewhat less incomplete than 0-bytes).

As for the backgrounds, PNG is the only format that supports an alpha channel, so the default pixel values of (0,0,0,0) will produce a transparent background (0 alpha), while JPEG and GIF images will ignore the alpha values and thus use the color of black (0,0,0). The white you see for PNG, is either the result of the surface you are drawing it on, or how your renderer shows transparent pixels when it doesn't handle an alpha channel.

If you want a black background, you should fill your image with (0,0,0,255) before starting. Also if writing PNG files, if you use image.NRGBA (non premultiplied alpha images), then encoding them to png files should be faster and lossless as they don't need to be converted first; although for non-transparent images the conversion should be lossless as well.

Graham MacDonald

unread,
Dec 5, 2013, 9:18:13 AM12/5/13
to golan...@googlegroups.com
Yeah, I'd forgotten my flushes.  Thanks for the explanation about the transparency issue.
Reply all
Reply to author
Forward
0 new messages