DarthSim 1 рік тому
батько
коміт
707a24e59d
6 змінених файлів з 25 додано та 11 видалено
  1. 1 0
      CHANGELOG.md
  2. 9 0
      imagetype/imagetype.go
  3. 1 10
      processing/processing.go
  4. 10 0
      vips/vips.c
  5. 3 1
      vips/vips.go
  6. 1 0
      vips/vips.h

+ 1 - 0
CHANGELOG.md

@@ -4,6 +4,7 @@
 ### Add
 - Add `status_codes_total` counter to Prometheus metrics.
 - Add client-side decryprion support for S3 integration.
+- Add HEIC saving support.
 - (pro) Add the `IMGPROXY_VIDEO_THUMBNAIL_KEYFRAMES` config and the [video_thumbnail_keyframes](https://docs.imgproxy.net/latest/generating_the_url?id=video-thumbnail-keyframes) processing option.
 - (pro) Add the [video_thumbnail_tile](https://docs.imgproxy.net/latest/generating_the_url?id=video-thumbnail-tile) processing option.
 - (pro) Add the `duration` field to the video streams information in the `/info` endpoint response.

+ 9 - 0
imagetype/imagetype.go

@@ -151,9 +151,18 @@ func (it Type) SupportsColourProfile() bool {
 	return it == JPEG ||
 		it == PNG ||
 		it == WEBP ||
+		it == HEIC ||
 		it == AVIF
 }
 
+func (it Type) SupportsQuality() bool {
+	return it == JPEG ||
+		it == WEBP ||
+		it == HEIC ||
+		it == AVIF ||
+		it == TIFF
+}
+
 func (it Type) SupportsThumbnail() bool {
 	return it == HEIC || it == AVIF
 }

+ 1 - 10
processing/processing.go

@@ -85,15 +85,6 @@ func ValidatePreferredFormats() error {
 	return nil
 }
 
-func canFitToBytes(imgtype imagetype.Type) bool {
-	switch imgtype {
-	case imagetype.JPEG, imagetype.WEBP, imagetype.AVIF, imagetype.TIFF:
-		return true
-	default:
-		return false
-	}
-}
-
 func getImageSize(img *vips.Image) (int, int) {
 	width, height, _, _ := extractMeta(img, 0, true)
 
@@ -339,7 +330,7 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
 		err     error
 	)
 
-	if po.MaxBytes > 0 && canFitToBytes(po.Format) {
+	if po.MaxBytes > 0 && po.Format.SupportsQuality() {
 		outData, err = saveImageToFitBytes(ctx, po, img)
 	} else {
 		outData, err = img.Save(po.Format, po.GetQuality())

+ 10 - 0
vips/vips.c

@@ -905,6 +905,16 @@ vips_tiffsave_go(VipsImage *in, void **buf, size_t *len, int quality)
   return vips_tiffsave_buffer(in, buf, len, "Q", quality, NULL);
 }
 
+int
+vips_heifsave_go(VipsImage *in, void **buf, size_t *len, int quality)
+{
+  return vips_heifsave_buffer(
+      in, buf, len,
+      "Q", quality,
+      "compression", VIPS_FOREIGN_HEIF_COMPRESSION_HEVC,
+      NULL);
+}
+
 int
 vips_avifsave_go(VipsImage *in, void **buf, size_t *len, int quality, int speed)
 {

+ 3 - 1
vips/vips.go

@@ -258,7 +258,7 @@ func SupportsSave(it imagetype.Type) bool {
 		sup = hasOperation("webpsave_buffer")
 	case imagetype.GIF:
 		sup = hasOperation("gifsave_buffer")
-	case imagetype.AVIF:
+	case imagetype.HEIC, imagetype.AVIF:
 		sup = hasOperation("heifsave_buffer")
 	case imagetype.BMP:
 		sup = true
@@ -389,6 +389,8 @@ func (img *Image) Save(imgtype imagetype.Type, quality int) (*imagedata.ImageDat
 		err = C.vips_webpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality))
 	case imagetype.GIF:
 		err = C.vips_gifsave_go(img.VipsImage, &ptr, &imgsize)
+	case imagetype.HEIC:
+		err = C.vips_heifsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality))
 	case imagetype.AVIF:
 		err = C.vips_avifsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality), vipsConf.AvifSpeed)
 	case imagetype.TIFF:

+ 1 - 0
vips/vips.h

@@ -87,6 +87,7 @@ int vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int q
     int colors);
 int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality);
 int vips_gifsave_go(VipsImage *in, void **buf, size_t *len);
+int vips_heifsave_go(VipsImage *in, void **buf, size_t *len, int quality);
 int vips_avifsave_go(VipsImage *in, void **buf, size_t *len, int quality, int speed);
 int vips_tiffsave_go(VipsImage *in, void **buf, size_t *len, int quality);