diff --git a/image_test.go b/image_test.go index fb20c62..e396857 100644 --- a/image_test.go +++ b/image_test.go @@ -246,6 +246,19 @@ func TestImageConvert(t *testing.T) { Write("fixtures/test_image_convert_out.png", buf) } +func TestTransparentImageConvert(t *testing.T) { + image := initImage("transparent.png") + options := Options{ + Type: JPEG, + Background: Color{255, 255, 255}, + } + buf, err := image.Process(options) + if err != nil { + t.Errorf("Cannot process the image: %#v", err) + } + Write("fixtures/test_transparent_image_convert_out.jpg", buf) +} + func TestImageMetadata(t *testing.T) { data, err := initImage("test.png").Metadata() if err != nil { diff --git a/options.go b/options.go index 9526914..0e7d2e4 100644 --- a/options.go +++ b/options.go @@ -123,4 +123,5 @@ type Options struct { Interpolator Interpolator Interpretation Interpretation GaussianBlur GaussianBlur + Background Color } diff --git a/resize.go b/resize.go index e234841..0ca1479 100644 --- a/resize.go +++ b/resize.go @@ -102,6 +102,15 @@ func Resize(buf []byte, o Options) ([]byte, error) { return nil, err } + // Flatten image on a background, if necessary + black := Color{0, 0, 0} + if imageType == PNG && o.Background != black { + image, err = vipsFlatten(image, o.Background) + if err != nil { + return nil, err + } + } + saveOptions := vipsSaveOptions{ Quality: o.Quality, Type: o.Type, diff --git a/vips.go b/vips.go index 9fcbc5b..8454231 100644 --- a/vips.go +++ b/vips.go @@ -252,6 +252,16 @@ func vipsInterpretation(image *C.VipsImage) Interpretation { return Interpretation(C.vips_image_guess_interpretation_bridge(image)) } +func vipsFlatten(image *C.VipsImage, background Color) (*C.VipsImage, error) { + var outImage *C.VipsImage + backgroundC := [3]C.double{C.double(background.R), C.double(background.G), C.double(background.B)} + err := int(C.vips_flatten_image(image, &outImage, (*C.double)(&backgroundC[0]))) + if err != 0 { + return nil, catchVipsError() + } + return outImage, nil +} + func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) { // Remove ICC profile metadata if o.NoProfile { diff --git a/vips.h b/vips.h index 0a52b39..4f75627 100644 --- a/vips.h +++ b/vips.h @@ -226,6 +226,15 @@ vips_webpsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int qual ); } +int +vips_flatten_image(VipsImage *in, VipsImage **out, double background[3]) { + VipsArrayDouble *vipsBackground = vips_array_double_new(background, 3); + return vips_flatten(in, out, + "background", vipsBackground, + NULL + ); +} + int vips_init_image (void *buf, size_t len, int imageType, VipsImage **out) { int code = 1;