Skip to content

Commit e112daf

Browse files
committed
feat: add page processing option.
1 parent 02360b2 commit e112daf

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

options/processing_options.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type ProcessingOptions struct {
7474
ZoomWidth float64
7575
ZoomHeight float64
7676
Dpr float64
77+
Page int
7778
Gravity GravityOptions
7879
Enlarge bool
7980
Extend ExtendOptions
@@ -159,6 +160,7 @@ func NewProcessingOptions() *ProcessingOptions {
159160
UsedPresets: make([]string, 0, len(config.Presets)),
160161

161162
SecurityOptions: security.DefaultOptions(),
163+
Page: -1,
162164

163165
// Basically, we need this to update ETag when `IMGPROXY_QUALITY` is changed
164166
defaultQuality: config.Quality,
@@ -807,6 +809,20 @@ func applySkipProcessingFormatsOption(po *ProcessingOptions, args []string) erro
807809
return nil
808810
}
809811

812+
func applyPageOption(po *ProcessingOptions, args []string) error {
813+
if len(args) > 1 {
814+
return newOptionArgumentError("Invalid page arguments: %v", args)
815+
}
816+
817+
if p, err := strconv.Atoi(args[0]); err == nil && p >= 0 {
818+
po.Page = p
819+
} else {
820+
return newOptionArgumentError("Invalid page: %s", args[0])
821+
}
822+
823+
return nil
824+
}
825+
810826
func applyRawOption(po *ProcessingOptions, args []string) error {
811827
if len(args) > 1 {
812828
return newOptionArgumentError("Invalid return_attachment arguments: %v", args)
@@ -1100,6 +1116,8 @@ func applyURLOption(po *ProcessingOptions, name string, args []string, usedPrese
11001116
return applyMaxAnimationFrameResolutionOption(po, args)
11011117
case "max_result_dimension", "mrd":
11021118
return applyMaxResultDimensionOption(po, args)
1119+
case "page":
1120+
return applyPageOption(po, args)
11031121
}
11041122

11051123
return newUnknownOptionError("processing", name)

processing/processing.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,27 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
283283
originWidth, originHeight := getImageSize(img)
284284

285285
animated := img.IsAnimated()
286+
287+
if po.Page >= 0 && animated {
288+
if po.Page >= img.Pages() {
289+
po.Page = img.Pages() - 1
290+
}
291+
292+
frameHeight := img.PageHeight()
293+
imgWidth := img.Width()
294+
295+
frame := new(vips.Image)
296+
if err := img.Extract(frame, 0, po.Page*frameHeight, imgWidth, frameHeight); err != nil {
297+
return nil, err
298+
}
299+
300+
// Swap extracted frame into `img` so deferred Clear() will free it,
301+
// and clear the temporary holder which now contains the original image.
302+
img.Swap(frame)
303+
frame.Clear()
304+
animated = false
305+
}
306+
286307
expectAlpha := !po.Flatten && (img.HasAlpha() || po.Padding.Enabled || po.Extend.Enabled)
287308

288309
switch {

0 commit comments

Comments
 (0)