MCPcopy Create free account
hub / github.com/imgproxy/imgproxy / saveImageToFitBytes

Function saveImageToFitBytes

processing/save_fit_bytes.go:18–81  ·  view source on GitHub ↗

saveImageToFitBytes tries to save the image to fit into the specified max bytes by lowering the quality. It returns the image data that fits the requirement or the best effort data if it was not possible to fit into the limit.

(
	ctx context.Context,
	img *vips.Image,
	format imagetype.Type,
	startQuality int,
	target int,
	o *options.Options,
)

Source from the content-addressed store, hash-verified

16// by lowering the quality. It returns the image data that fits the requirement
17// or the best effort data if it was not possible to fit into the limit.
18func saveImageToFitBytes(
19 ctx context.Context,
20 img *vips.Image,
21 format imagetype.Type,
22 startQuality int,
23 target int,
24 o *options.Options,
25) (imagedata.ImageData, error) {
26 var newQuality int
27
28 // Start with the specified quality and go down from there.
29 quality := startQuality
30
31 // We will probably save the image multiple times, so we need to process its pixels
32 // to ensure that it is in random access mode.
33 if err := img.CopyMemory(); err != nil {
34 return nil, err
35 }
36
37 for {
38 // Check for timeout or cancellation before each attempt as we might spend too much
39 // time processing the image or making previous attempts.
40 if err := server.CheckTimeout(ctx); err != nil {
41 return nil, err
42 }
43
44 o.Set(keys.Quality, quality)
45
46 imgdata, err := img.Save(format, quality, o)
47 if err != nil {
48 return nil, err
49 }
50
51 size, err := imgdata.Size()
52 if err != nil {
53 imgdata.Close()
54 return nil, err
55 }
56
57 // If we fit the limit or quality is too low, return the result.
58 if size <= target || quality <= 10 {
59 return imgdata, err
60 }
61
62 // We don't need the image data anymore, close it to free resources.
63 imgdata.Close()
64
65 // Tune quality for the next attempt based on how much we exceed the limit.
66 delta := float64(size) / float64(target)
67 switch {
68 case delta > 3:
69 newQuality = imath.Scale(quality, 0.25)
70 case delta > 1.5:
71 newQuality = imath.Scale(quality, 0.5)
72 default:
73 newQuality = imath.Scale(quality, 0.75)
74 }
75

Callers 1

saveImageMethod · 0.85

Calls 7

CheckTimeoutFunction · 0.92
ScaleFunction · 0.92
CopyMemoryMethod · 0.80
SaveMethod · 0.80
SizeMethod · 0.65
CloseMethod · 0.65
SetMethod · 0.45

Tested by

no test coverage detected