mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
feat(chromium): add clip options to screenshot routes
This commit is contained in:
@@ -258,6 +258,7 @@ func (b *chromiumBrowser) screenshot(ctx context.Context, logger *zap.Logger, ur
|
||||
waitDelayBeforePrintActionFunc(logger, b.arguments.disableJavaScript, options.WaitDelay),
|
||||
waitForExpressionBeforePrintActionFunc(logger, b.arguments.disableJavaScript, options.WaitForExpression),
|
||||
// Screenshot specific.
|
||||
setDeviceMetricsOverride(logger, options.Width, options.Height),
|
||||
captureScreenshotActionFunc(logger, outputPath, options),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1996,6 +1996,54 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
"no emulated media type",
|
||||
"no wait delay",
|
||||
"no wait expression",
|
||||
"set device metrics override",
|
||||
},
|
||||
},
|
||||
{
|
||||
scenario: "success (clip)",
|
||||
browser: newChromiumBrowser(
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
fs := gotenberg.NewFileSystem()
|
||||
|
||||
err := os.MkdirAll(fs.WorkingDirPath(), 0o755)
|
||||
if err != nil {
|
||||
t.Fatalf(fmt.Sprintf("expected no error but got: %v", err))
|
||||
}
|
||||
|
||||
err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("<h1>Default options</h1>"), 0o755)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return fs
|
||||
}(),
|
||||
options: func() ScreenshotOptions {
|
||||
options := DefaultScreenshotOptions()
|
||||
options.Clip = true
|
||||
return options
|
||||
}(),
|
||||
noDeadline: false,
|
||||
start: true,
|
||||
expectError: false,
|
||||
expectedLogEntries: []string{
|
||||
"cache not cleared",
|
||||
"cookies not cleared",
|
||||
"JavaScript not disabled",
|
||||
"no cookies to set",
|
||||
"no extra HTTP headers",
|
||||
"navigate to",
|
||||
"default white background not hidden",
|
||||
"no emulated media type",
|
||||
"no wait delay",
|
||||
"no wait expression",
|
||||
"set device metrics override",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -2042,6 +2090,7 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
"no emulated media type",
|
||||
"no wait delay",
|
||||
"no wait expression",
|
||||
"set device metrics override",
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
||||
@@ -239,6 +239,19 @@ func DefaultPdfOptions() PdfOptions {
|
||||
type ScreenshotOptions struct {
|
||||
Options
|
||||
|
||||
// Width is the device screen width in pixels.
|
||||
// Optional.
|
||||
Width int
|
||||
|
||||
// Height is the device screen height in pixels.
|
||||
// Optional.
|
||||
Height int
|
||||
|
||||
// Clip defines whether to clip the screenshot according to the device
|
||||
// dimensions.
|
||||
// Optional.
|
||||
Clip bool
|
||||
|
||||
// Format is the image compression format, either "png" or "jpeg" or
|
||||
// "webp".
|
||||
// Optional.
|
||||
@@ -258,6 +271,9 @@ type ScreenshotOptions struct {
|
||||
func DefaultScreenshotOptions() ScreenshotOptions {
|
||||
return ScreenshotOptions{
|
||||
Options: DefaultOptions(),
|
||||
Width: 800,
|
||||
Height: 600,
|
||||
Clip: false,
|
||||
Format: "png",
|
||||
Quality: 100,
|
||||
OptimizeForSpeed: false,
|
||||
|
||||
@@ -182,12 +182,17 @@ func FormDataChromiumScreenshotOptions(ctx *api.Context) (*api.FormData, Screens
|
||||
defaultScreenshotOptions := DefaultScreenshotOptions()
|
||||
|
||||
var (
|
||||
width, height int
|
||||
clip bool
|
||||
format string
|
||||
quality int
|
||||
optimizeForSpeed bool
|
||||
)
|
||||
|
||||
form.
|
||||
Int("width", &width, defaultScreenshotOptions.Width).
|
||||
Int("height", &height, defaultScreenshotOptions.Height).
|
||||
Bool("clip", &clip, defaultScreenshotOptions.Clip).
|
||||
Custom("format", func(value string) error {
|
||||
if value == "" {
|
||||
format = defaultScreenshotOptions.Format
|
||||
@@ -228,6 +233,9 @@ func FormDataChromiumScreenshotOptions(ctx *api.Context) (*api.FormData, Screens
|
||||
|
||||
screenshotOptions := ScreenshotOptions{
|
||||
Options: options,
|
||||
Width: width,
|
||||
Height: height,
|
||||
Clip: clip,
|
||||
Format: format,
|
||||
Quality: quality,
|
||||
OptimizeForSpeed: optimizeForSpeed,
|
||||
|
||||
@@ -385,6 +385,15 @@ func TestFormDataChromiumScreenshotOptions(t *testing.T) {
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetValues(map[string][]string{
|
||||
"width": {
|
||||
"1280",
|
||||
},
|
||||
"height": {
|
||||
"800",
|
||||
},
|
||||
"clip": {
|
||||
"true",
|
||||
},
|
||||
"optimizeForSpeed": {
|
||||
"true",
|
||||
},
|
||||
@@ -396,6 +405,9 @@ func TestFormDataChromiumScreenshotOptions(t *testing.T) {
|
||||
}(),
|
||||
expectedOptions: func() ScreenshotOptions {
|
||||
options := DefaultScreenshotOptions()
|
||||
options.Width = 1280
|
||||
options.Height = 800
|
||||
options.Clip = true
|
||||
options.OptimizeForSpeed = true
|
||||
options.EmulatedMediaType = "screen"
|
||||
return options
|
||||
|
||||
@@ -121,6 +121,14 @@ func captureScreenshotActionFunc(logger *zap.Logger, outputPath string, options
|
||||
WithOptimizeForSpeed(options.OptimizeForSpeed).
|
||||
WithFormat(page.CaptureScreenshotFormat(options.Format))
|
||||
|
||||
if options.Clip {
|
||||
captureScreenshot = captureScreenshot.WithClip(&page.Viewport{
|
||||
Width: float64(options.Width),
|
||||
Height: float64(options.Height),
|
||||
Scale: 1,
|
||||
})
|
||||
}
|
||||
|
||||
if options.Format == "jpeg" {
|
||||
captureScreenshot = captureScreenshot.
|
||||
WithQuality(int64(options.Quality))
|
||||
@@ -154,6 +162,19 @@ func captureScreenshotActionFunc(logger *zap.Logger, outputPath string, options
|
||||
}
|
||||
}
|
||||
|
||||
func setDeviceMetricsOverride(logger *zap.Logger, width, height int) chromedp.ActionFunc {
|
||||
return func(ctx context.Context) error {
|
||||
logger.Debug("set device metrics override")
|
||||
|
||||
err := emulation.SetDeviceMetricsOverride(int64(width), int64(height), 1.0, false).Do(ctx)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("set device metrics override: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
func clearCacheActionFunc(logger *zap.Logger, clear bool) chromedp.ActionFunc {
|
||||
return func(ctx context.Context) error {
|
||||
// See https://github.com/gotenberg/gotenberg/issues/753.
|
||||
|
||||
Reference in New Issue
Block a user