Saving PNG as JPEG with Transparency

709 views
Skip to first unread message

Alexander Lücking

unread,
Apr 27, 2015, 9:15:09 AM4/27/15
to golan...@googlegroups.com
Hi,

I want to save PNG that has transparent areas as a JPEG.
The transparent areas are automatically drawn as black because jpeg does not support transparency.

Is there a way to change the automatic transparency color from black to something else?

Egon

unread,
Apr 27, 2015, 9:36:45 AM4/27/15
to golan...@googlegroups.com
Create a new background image and blend the PNG together with the background image. (https://golang.org/pkg/image/draw/#Draw)

This should do it... (note untested)...

background := image.NewRGBA(image.Bounds())
for i := 0; i < len(img.Pix); i += 4 {
  img.Pix[i] = 0xFF
  img.Pix[i+1] = 0xFF
  img.Pix[i+2] = 0xFF
  img.Pix[i+3] = 0xFF // can't remember whether this should 0xFF or 0x00
}

draw.Draw(background, background.Bounds(), source, image.Point{0,0}, draw.Src)

Alternatively convert the png image to a image.RGBA, and handle the blending to your destination color yourself.

+ Egon

Nigel Tao

unread,
Apr 27, 2015, 9:00:55 PM4/27/15
to Egon, golang-nuts
On Mon, Apr 27, 2015 at 11:36 PM, Egon <egon...@gmail.com> wrote:
> background := image.NewRGBA(image.Bounds())
> for i := 0; i < len(img.Pix); i += 4 {
> img.Pix[i] = 0xFF
> img.Pix[i+1] = 0xFF
> img.Pix[i+2] = 0xFF
> img.Pix[i+3] = 0xFF // can't remember whether this should 0xFF or 0x00
> }

This should be 0xFF, since the final value of an RGBA is opacity, not
transparency.

An easier approach, though, is to use the draw package. See the
"Filling a Rectangle" section of
http://blog.golang.org/go-imagedraw-package


> draw.Draw(background, background.Bounds(), source, image.Point{0,0},
> draw.Src)

The draw.Src there should be draw.Over.

Here's a complete program.

----
package main

import (
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"log"
"os"
)

func main() {
backgroundColor := color.RGBA{0x7f, 0x00, 0x00, 0xff} // Dark red.

srcFile, err := os.Open("in.png")
if err != nil {
log.Fatal(err)
}
defer srcFile.Close()
src, err := png.Decode(srcFile)
if err != nil {
log.Fatal(err)
}

dst := image.NewRGBA(src.Bounds())
draw.Draw(dst, dst.Bounds(), image.NewUniform(backgroundColor),
image.Point{}, draw.Src)
draw.Draw(dst, dst.Bounds(), src, src.Bounds().Min, draw.Over)

dstFile, err := os.Create("out.jpeg")
if err != nil {
log.Fatal(err)
}
defer dstFile.Close()
err = jpeg.Encode(dstFile, dst, nil)
if err != nil {
log.Fatal(err)
}
}
----
Reply all
Reply to author
Forward
0 new messages