Strip metadata from processed images (closes #82)
check / check (push) Successful in 2m59s

Every output is exported with govips' StripMetadata, so it carries no
EXIF, XMP, IPTC or ICC profile, the orig format included: it is always
re-encoded, and pixa never serves the source bytes. The image is turned
upright with AutoRotate right after decoding, so dropping the
orientation tag does not leave it rotated, and a requested size applies
to the upright image. An image with an ICC profile is converted to sRGB
before export, since clients show an image with no profile as sRGB.
No setting turns this off. README.md documents it.

Model: opus-5-5
This commit is contained in:
2026-09-28 23:56:21 +00:00
parent b3e59e7855
commit f5902f4241
3 changed files with 43 additions and 1 deletions
+22
View File
@@ -161,6 +161,13 @@ func (p *ImageProcessor) Process(
}
defer img.Close()
// Turn the image upright now: encode strips the EXIF orientation tag,
// and sizes below must be worked out on the upright image.
err = img.AutoRotate()
if err != nil {
return nil, fmt.Errorf("failed to auto-rotate: %w", err)
}
// Get original dimensions
origWidth := img.Width()
origHeight := img.Height()
@@ -404,6 +411,21 @@ func (p *ImageProcessor) encode(
return nil, fmt.Errorf("%w: %s", ErrUnsupportedOutputFormat, format)
}
// Stripping drops the ICC profile as well, and clients show an image
// with no profile as sRGB, so convert to sRGB first. "srgb" names
// libvips' built-in profile; govips' own sRGB path variable is set on
// first use but read without a lock, so concurrent requests race on it.
if img.HasICCProfile() {
err := img.TransformICCProfileWithFallback("srgb", "srgb")
if err != nil {
return nil, fmt.Errorf("failed to convert to sRGB: %w", err)
}
}
// Drop EXIF, XMP, IPTC and the ICC profile. govips ignores this for
// GIF, which carries none of them.
params.StripMetadata = true
output, _, err := img.Export(&params)
if err != nil {
return nil, err