1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-02-07 11:36:25 +02:00

Add option to keep metadata/tags in output image (#329)

* add env var to disable stripping metadata

by default, all metadata will be stripped (as before)

* always strip orientation tags when rotating the image

in case IMGPROXY_STRIP_METADATA is false

* document IMGPROXY_STRIP_METADATA env var

* remove ICC profile after importing it

needed, in case metadata aren't stripped from the output image
This commit is contained in:
sauerbraten 2020-01-30 16:43:08 +01:00 committed by GitHub
parent aa8cff62f4
commit 89f8a4e11c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 43 deletions

View File

@ -166,6 +166,7 @@ type config struct {
PngQuantizationColors int
Quality int
GZipCompression int
StripMetadata bool
EnableWebpDetection bool
EnforceWebp bool
@ -242,6 +243,7 @@ var conf = config{
SignatureSize: 32,
PngQuantizationColors: 256,
Quality: 80,
StripMetadata: true,
UserAgent: fmt.Sprintf("imgproxy/%s", version),
Presets: make(presets),
WatermarkOpacity: 1,
@ -300,6 +302,7 @@ func configure() {
intEnvConfig(&conf.PngQuantizationColors, "IMGPROXY_PNG_QUANTIZATION_COLORS")
intEnvConfig(&conf.Quality, "IMGPROXY_QUALITY")
intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
boolEnvConfig(&conf.StripMetadata, "IMGPROXY_STRIP_METADATA")
boolEnvConfig(&conf.EnableWebpDetection, "IMGPROXY_ENABLE_WEBP_DETECTION")
boolEnvConfig(&conf.EnforceWebp, "IMGPROXY_ENFORCE_WEBP")

View File

@ -253,3 +253,4 @@ imgproxy can send logs to syslog, but this feature is disabled by default. To en
* `IMGPROXY_USE_LINEAR_COLORSPACE`: when `true`, imgproxy will process images in linear colorspace. This will slow down processing. Note that images won't be fully processed in linear colorspace while shrink-on-load is enabled (see below).
* `IMGPROXY_DISABLE_SHRINK_ON_LOAD`: when `true`, disables shrink-on-load for JPEG and WebP. Allows to process the whole image in linear colorspace but dramatically slows down resizing and increases memory usage when working with large images.
* `IMGPROXY_APPLY_UNSHARPEN_MASKING`: <img class="pro-badge" src="assets/pro.svg" alt="pro" /> when `true`, imgproxy will apply unsharpen masking to the resulting image if one is smaller than the source. Default: `true`.
* `IMGPROXY_STRIP_METADATA`: whether to strip all metadata (EXIF, IPTC, etc.) from JPEG and WebP output images. Default: `true`.

View File

@ -609,7 +609,7 @@ func saveImageToFitBytes(po *processingOptions, img *vipsImage) ([]byte, context
img.CopyMemory()
for {
result, cancel, err := img.Save(po.Format, quality)
result, cancel, err := img.Save(po.Format, quality, po.StripMetadata)
if len(result) <= po.MaxBytes || quality <= 10 || err != nil {
return result, cancel, err
}
@ -737,5 +737,5 @@ func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
return saveImageToFitBytes(po, img)
}
return img.Save(po.Format, po.Quality)
return img.Save(po.Format, po.Quality, po.StripMetadata)
}

View File

@ -125,6 +125,7 @@ type processingOptions struct {
Trim trimOptions
Format imageType
Quality int
StripMetadata bool
MaxBytes int
Flatten bool
Background rgbColor
@ -206,6 +207,7 @@ func newProcessingOptions() *processingOptions {
Extend: extendOptions{Enabled: false, Gravity: gravityOptions{Type: gravityCenter}},
Trim: trimOptions{Enabled: false, Threshold: 10},
Quality: conf.Quality,
StripMetadata: conf.StripMetadata,
MaxBytes: 0,
Format: imageTypeUnknown,
Background: rgbColor{255, 255, 255},

15
vips.c
View File

@ -338,7 +338,12 @@ vips_support_builtin_icc() {
int
vips_icc_import_go(VipsImage *in, VipsImage **out, char *profile) {
return vips_icc_import(in, out, "input_profile", profile, "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL);
if (vips_icc_import(in, out, "input_profile", profile, "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL))
return 1;
vips_image_remove(*out, VIPS_META_ICC_NAME);
return 0;
}
int
@ -512,8 +517,8 @@ vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n) {
}
int
vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace) {
return vips_jpegsave_buffer(in, buf, len, "profile", "none", "Q", quality, "strip", TRUE, "optimize_coding", TRUE, "interlace", interlace, NULL);
vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace, gboolean strip) {
return vips_jpegsave_buffer(in, buf, len, "profile", "none", "Q", quality, "strip", strip, "optimize_coding", TRUE, "interlace", interlace, NULL);
}
int
@ -531,8 +536,8 @@ vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int quant
}
int
vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality) {
return vips_webpsave_buffer(in, buf, len, "Q", quality, "strip", TRUE, NULL);
vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality, gboolean strip) {
return vips_webpsave_buffer(in, buf, len, "Q", quality, "strip", strip, NULL);
}
int

15
vips.go
View File

@ -130,6 +130,13 @@ func vipsLoadWatermark() (err error) {
return
}
func gbool(b bool) C.gboolean {
if b {
return C.gboolean(1)
}
return C.gboolean(0)
}
func (img *vipsImage) Width() int {
return int(img.VipsImage.Xsize)
}
@ -170,7 +177,7 @@ func (img *vipsImage) Load(data []byte, imgtype imageType, shrink int, scale flo
return nil
}
func (img *vipsImage) Save(imgtype imageType, quality int) ([]byte, context.CancelFunc, error) {
func (img *vipsImage) Save(imgtype imageType, quality int, stripMeta bool) ([]byte, context.CancelFunc, error) {
var ptr unsafe.Pointer
cancel := func() {
@ -183,11 +190,11 @@ func (img *vipsImage) Save(imgtype imageType, quality int) ([]byte, context.Canc
switch imgtype {
case imageTypeJPEG:
err = C.vips_jpegsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality), vipsConf.JpegProgressive)
err = C.vips_jpegsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality), vipsConf.JpegProgressive, gbool(stripMeta))
case imageTypePNG:
err = C.vips_pngsave_go(img.VipsImage, &ptr, &imgsize, vipsConf.PngInterlaced, vipsConf.PngQuantize, vipsConf.PngQuantizationColors)
case imageTypeWEBP:
err = C.vips_webpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality))
err = C.vips_webpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality), gbool(stripMeta))
case imageTypeGIF:
err = C.vips_gifsave_go(img.VipsImage, &ptr, &imgsize)
case imageTypeICO:
@ -312,6 +319,8 @@ func (img *vipsImage) Rotate(angle int) error {
return vipsError()
}
C.vips_autorot_remove_angle(tmp)
C.swap_and_clear(&img.VipsImage, tmp)
return nil
}

4
vips.h
View File

@ -82,9 +82,9 @@ int vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, d
int vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n);
int vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace);
int vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace, gboolean strip);
int vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int quantize, int colors);
int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality);
int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality, gboolean strip);
int vips_gifsave_go(VipsImage *in, void **buf, size_t *len);
int vips_icosave_go(VipsImage *in, void **buf, size_t *len);
int vips_heifsave_go(VipsImage *in, void **buf, size_t *len, int quality);