浏览代码

Fix padding and extend behaior when converting from a fromat without alpha support to one with alpha support

DarthSim 5 年之前
父节点
当前提交
965cd68ecf
共有 6 个文件被更改,包括 33 次插入8 次删除
  1. 2 1
      CHANGELOG.md
  2. 4 0
      image_type.go
  3. 5 2
      process.go
  4. 5 0
      vips.c
  5. 15 5
      vips.go
  6. 2 0
      vips.h

+ 2 - 1
CHANGELOG.md

@@ -11,7 +11,8 @@
 - Speed up generation of video thumbnails with large timestamps.
 
 ### Fix
-- Fix thumbnails generation of some videos.
+- Fix `padding` and `extend` behaior when converting from a fromat without alpha support to one with alpha support
+- (pro) Fix thumbnails generation of some videos.
 
 ## [2.14.1] - 2020-07-22
 ### Fix

+ 4 - 0
image_type.go

@@ -117,3 +117,7 @@ func (it imageType) ContentDispositionFromURL(imageURL string) string {
 
 	return it.ContentDisposition(strings.TrimSuffix(filename, filepath.Ext(filename)))
 }
+
+func (it imageType) SupportsAlpha() bool {
+	return it != imageTypeJPEG && it != imageTypeBMP
+}

+ 5 - 2
process.go

@@ -266,7 +266,7 @@ func prepareWatermark(wm *vipsImage, wmData *imageData, opts *watermarkOptions,
 
 	left, top := calcPosition(imgWidth, imgHeight, wm.Width(), wm.Height(), &opts.Gravity, true)
 
-	return wm.Embed(imgWidth, imgHeight, left, top, rgbColor{0, 0, 0})
+	return wm.Embed(imgWidth, imgHeight, left, top, rgbColor{0, 0, 0}, true)
 }
 
 func applyWatermark(img *vipsImage, wmData *imageData, opts *watermarkOptions, framesCount int) error {
@@ -430,6 +430,8 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 		return err
 	}
 
+	transparrentBg := po.Format.SupportsAlpha() && !po.Flatten
+
 	if hasAlpha && (po.Flatten || po.Format == imageTypeJPEG) {
 		if err = img.Flatten(po.Background); err != nil {
 			return err
@@ -456,7 +458,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 
 	if po.Extend.Enabled && (po.Width > img.Width() || po.Height > img.Height()) {
 		offX, offY := calcPosition(po.Width, po.Height, img.Width(), img.Height(), &po.Extend.Gravity, false)
-		if err = img.Embed(po.Width, po.Height, offX, offY, po.Background); err != nil {
+		if err = img.Embed(po.Width, po.Height, offX, offY, po.Background, transparrentBg); err != nil {
 			return err
 		}
 	}
@@ -472,6 +474,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 			paddingLeft,
 			paddingTop,
 			po.Background,
+			transparrentBg,
 		); err != nil {
 			return err
 		}

+ 5 - 0
vips.c

@@ -250,6 +250,11 @@ vips_image_hasalpha_go(VipsImage * in) {
 #endif
 }
 
+int
+vips_addalpha_go(VipsImage *in, VipsImage **out) {
+  return vips_addalpha(in, out, NULL);
+}
+
 int
 vips_copy_go(VipsImage *in, VipsImage **out) {
   return vips_copy(in, out, NULL);

+ 15 - 5
vips.go

@@ -590,20 +590,30 @@ func (img *vipsImage) Replicate(width, height int) error {
 	return nil
 }
 
-func (img *vipsImage) Embed(width, height int, offX, offY int, bg rgbColor) error {
+func (img *vipsImage) Embed(width, height int, offX, offY int, bg rgbColor, transpBg bool) error {
+	var tmp *C.VipsImage
+
 	if err := img.RgbColourspace(); err != nil {
 		return err
 	}
 
 	var bgc []C.double
-	if img.HasAlpha() {
+	if transpBg {
+		if !img.HasAlpha() {
+			if C.vips_addalpha_go(img.VipsImage, &tmp) != 0 {
+				return vipsError()
+			}
+			C.swap_and_clear(&img.VipsImage, tmp)
+		}
+
 		bgc = []C.double{C.double(0)}
 	} else {
-		bgc = []C.double{C.double(bg.R), C.double(bg.G), C.double(bg.B)}
+		bgc = []C.double{C.double(bg.R), C.double(bg.G), C.double(bg.B), 1.0}
 	}
 
-	var tmp *C.VipsImage
-	if C.vips_embed_go(img.VipsImage, &tmp, C.int(offX), C.int(offY), C.int(width), C.int(height), &bgc[0], C.int(len(bgc))) != 0 {
+	bgn := minInt(int(img.VipsImage.Bands), len(bgc))
+
+	if C.vips_embed_go(img.VipsImage, &tmp, C.int(offX), C.int(offY), C.int(width), C.int(height), &bgc[0], C.int(bgn)) != 0 {
 		return vipsError()
 	}
 	C.swap_and_clear(&img.VipsImage, tmp)

+ 2 - 0
vips.h

@@ -45,7 +45,9 @@ VipsBandFormat vips_band_format(VipsImage *in);
 
 gboolean vips_support_webp_animation();
 gboolean vips_is_animated(VipsImage * in);
+
 gboolean vips_image_hasalpha_go(VipsImage * in);
+int vips_addalpha_go(VipsImage *in, VipsImage **out);
 
 int vips_copy_go(VipsImage *in, VipsImage **out);