composite a png over a jpg file,and then encode to avif, then failed and ”[VIPS.warning] Not a PNG file“
I want do watermark handle。 And my operrateion is use a jpg as base file, and the overlay file is png。 When i do the operation by Composite api, it will failed, and report ”[VIPS.warning] Not a PNG file“。 the stack is under below:
Scene appears:if the server only one request, it's ok。 when the server is busy, which has multiple concurrent requests, then it will failed.
Please help me give some handle advice, thank you.
err="\nStack:\ngoroutine 5451 [running]:\nruntime/debug.Stack()\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0x65\ngithub.com/davidbyttow/govips/v2/vips.handleVipsError()\n\t/var/lib/docker/columbus/repo/pkg_repo/2024082016/148556/45906816/1724141011449/src_repo/server/vendor/github.com/davidbyttow/govips/v2/vips/error.go:38 +0x57\ngithub.com/davidbyttow/govips/v2/vips.handleSaveBufferError(0xc00004a000?)\n\t/var/lib/docker/columbus/repo/pkg_repo/2024082016/148556/45906816/1724141011449/src_repo/server/vendor/github.com/davidbyttow/govips/v2/vips/error.go:31 +0x25\ngithub.com/davidbyttow/govips/v2/vips.vipsSaveToBuffer({0x7ff57e5f6e10, 0x0, 0xb, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x1, 0x0, ...})\n\t/var/lib/docker/columbus/repo/pkg_repo/2024082016/148556/45906816/1724141011449/src_repo/server/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go:520 +0xa5\ngithub.com/davidbyttow/govips/v2/vips.vipsSaveAVIFToBuffer(0x7ff57e5f6e10, {0x0, 0x2d, 0x0, 0x6, 0x5})\n\t/var/lib/docker/columbus/repo/pkg_repo/2024082016/148556/45906816/1724141011449/src_repo/server/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go:487 +0x158\ngithub.com/davidbyttow/govips/v2/vips.(*ImageRef).ExportAvif(0xc0001674f0, 0xc0001705d0?)\n\t/var/lib/docker/columbus/repo/pkg_repo/2024082016/148556/45906816/1724141011449/src_repo/server/vendor/github.com/davidbyttow/govips/v2/vips/image.go:994 +0xa5\ngithub.com/davidbyttow/govips/v2/vips.(*ImageRef).Export(0xc0001674f0?, 0xc00059e000)\
Looks like it's just saving to a buffer when there's an error. Could this be an out of memory issue or something similar?
Looks like it's just saving to a buffer when there's an error. Could this be an out of memory issue or something similar?
When the server doesn't have concurrent req, it will be ok. So if out of memory, single req will be alos failed, but it is not happend.
My step is: start a server, then a script do common req continuously:such as only do webp export。 And then a req for watermark continuously, then fail will happend quickly.
I have a try to avoid and reduce probability of the problem.
Origin Step: do concurrent req,has a high probability of problem occurrence 1 one jpg, a png which is for watermark 2 do resize and crop 3 do watermark 4 export webp or avif will fail
avoidance plan step: 1 one jpg, a png which is for watermark 2 do resize and crop 3 export result to jpg, and reload the jpg 4 do watermark 5 export webp or avif
I think,maybe the handle goroutine mem is too high, but i haven't no idea to find where the problem is.
I've encountered the same issue today. It seems like govips is doing operations lazily and GC frees some resources earlier than they're used. I've been able to reproduce only from time to time but it looks like it depends on number of transformations of source images. My usecase is:
- base picture, do some cropping, resizing etc
- overlay picture - again, do some resizing, conversions
- now .Overlay() or .Insert() and there is a decent chance it will trigger the issue
Interesting is that I'm able to reproduce it more frequently when using over http than in a standalone binary (which I need to run over and over to trigger this from time to time). My workaround is to do:
err := base.Insert(overlay, x, y, false, &vips.ColorRGBA{R: 0, G: 0, B: 0, A: 255})
if err != nil {
return fmt.Errorf("failed to composite images: %w, bands: %d / %d", err, base.Bands(), overlay.Bands())
}
// this is necessary because of some bug of free after use in govips
// we need to ensure operations are performed before the image is used
// so GC doesn't free the image prematurely
_, err = base.ToImage(vips.NewDefaultPNGExportParams())
if err != nil {
return fmt.Errorf("failed to convert image to PNG: %w", err)
}
With this arbitrary ToImage() I think I force govips to perform operations and can free the sources. Anyway - it "fixed" my issue.
@nextsux It seems like just exporting via .Export() or .ExportPng() is faster yet also prevents this issue
Example:
_, _, err = base.ExportPng(vips.NewPngExportParams())