Browse Source

Fix applying replicated PNG watermarks

DarthSim 2 years ago
parent
commit
8bd3d5d472
1 changed files with 25 additions and 11 deletions
  1. 25 11
      processing/watermark.go

+ 25 - 11
processing/watermark.go

@@ -19,7 +19,7 @@ var watermarkPipeline = pipeline{
 	padding,
 }
 
-func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options.WatermarkOptions, imgWidth, imgHeight int) error {
+func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options.WatermarkOptions, imgWidth, imgHeight, framesCount int) error {
 	if err := wm.Load(wmData, 1, 1.0, 1); err != nil {
 		return err
 	}
@@ -47,13 +47,33 @@ func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options
 		return err
 	}
 
+	if opts.Replicate || framesCount > 1 {
+		// We need to copy image if we're going to replicate.
+		// Replication requires image to be read several times, and this requires
+		// random access to pixels
+		if err := wm.CopyMemory(); err != nil {
+			return err
+		}
+	}
+
 	if opts.Replicate {
-		return wm.Replicate(imgWidth, imgHeight)
+		if err := wm.Replicate(imgWidth, imgHeight); err != nil {
+			return err
+		}
+	} else {
+		left, top := calcPosition(imgWidth, imgHeight, wm.Width(), wm.Height(), &opts.Gravity, true)
+		if err := wm.Embed(imgWidth, imgHeight, left, top); err != nil {
+			return err
+		}
 	}
 
-	left, top := calcPosition(imgWidth, imgHeight, wm.Width(), wm.Height(), &opts.Gravity, true)
+	if framesCount > 1 {
+		if err := wm.Replicate(imgWidth, imgWidth*framesCount); err != nil {
+			return err
+		}
+	}
 
-	return wm.Embed(imgWidth, imgHeight, left, top)
+	return nil
 }
 
 func applyWatermark(img *vips.Image, wmData *imagedata.ImageData, opts *options.WatermarkOptions, framesCount int) error {
@@ -67,16 +87,10 @@ func applyWatermark(img *vips.Image, wmData *imagedata.ImageData, opts *options.
 	width := img.Width()
 	height := img.Height()
 
-	if err := prepareWatermark(wm, wmData, opts, width, height/framesCount); err != nil {
+	if err := prepareWatermark(wm, wmData, opts, width, height/framesCount, framesCount); err != nil {
 		return err
 	}
 
-	if framesCount > 1 {
-		if err := wm.Replicate(width, height); err != nil {
-			return err
-		}
-	}
-
 	opacity := opts.Opacity * config.WatermarkOpacity
 
 	return img.ApplyWatermark(wm, opacity)