New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blank or cut screenshots when using high resolutions #1137
Comments
Please provide the URL they can be used to reproduce the issue. |
Hey thanks for the quick response :) |
I can get the expected screenshot on both Ubuntu and iMac with this demo: package main
import (
"context"
"io/ioutil"
"log"
"github.com/chromedp/chromedp"
)
func main() {
// create context
ctx, cancel := chromedp.NewContext(
context.Background(),
// chromedp.WithDebugf(log.Printf),
)
defer cancel()
var buf []byte
// capture entire browser viewport
if err := chromedp.Run(ctx,
chromedp.Navigate("https://magic-mondrian.netlify.app/screenshot?mintAddress=0xe3bbf29f034fA780407Fd11dac7A0B3938b1bc6a&tokenId=1×tamp=1660606604&url=ipfs://bafybeienieybucxgxkw6tspsjoxb5jj4kbsljbckck2e4r3pymyiilhzza/5.svg"),
chromedp.EmulateViewport(7086, 9448),
chromedp.WaitVisible(`mondrian`, chromedp.ByID),
chromedp.FullScreenshot(&buf, 100),
); err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile("fullScreenshot.png", buf, 0o644); err != nil {
log.Fatal(err)
}
} Did I miss anything? |
I tested this on an M1 Macbook Pro btw. |
That's because the image is not fully loaded before you capture the screenshot. You have to wait until the image is fully loaded. Please note that package main
import (
"context"
"io/ioutil"
"log"
"sync"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(
context.Background(),
// chromedp.WithDebugf(log.Printf),
)
defer cancel()
var wg sync.WaitGroup
wg.Add(1)
chromedp.ListenTarget(ctx, func(ev interface{}) {
if ev, ok := ev.(*page.EventLifecycleEvent); ok {
if ev.Name == "firstMeaningfulPaint" {
wg.Done()
}
}
})
var buf []byte
// capture entire browser viewport
if err := chromedp.Run(ctx,
chromedp.Navigate("https://magic-mondrian.netlify.app/screenshot?mintAddress=0xe3bbf29f034fA780407Fd11dac7A0B3938b1bc6a&tokenId=1×tamp=1660606604&url=ipfs://bafybeienieybucxgxkw6tspsjoxb5jj4kbsljbckck2e4r3pymyiilhzza/5.svg"),
chromedp.EmulateViewport(7086, 9448),
chromedp.ActionFunc(func(ctx context.Context) error {
wg.Wait()
return nil
}),
chromedp.FullScreenshot(&buf, 100),
); err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile("fullScreenshot.png", buf, 0o644); err != nil {
log.Fatal(err)
}
} |
Not really sure what to do now, the code you posted has the same result. How can I reliably wait? I am also not really familiar with golang, but I wanted to try it since I used puppeteer for node js before, but I had the exact same problem. I find it also really strange that texts are cut off, because this is something that doesn't need to be loaded via an API call. Text information should be there immediately. It feels like the image is generated from top to bottom and if it is saved too early, it gets cut off at the point where the "image generator" was. |
Sorry that I haven't provided the correct event to wait for. Like I said before, you have to study the page to find a way to determine whether that page is fully loaded. Maybe you can wait for the svg file is received. Please try the next demo: package main
import (
"context"
"io/ioutil"
"log"
"sync"
"github.com/chromedp/cdproto/network"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(
context.Background(),
// chromedp.WithDebugf(log.Printf),
)
defer cancel()
var wg sync.WaitGroup
wg.Add(1)
chromedp.ListenTarget(ctx, func(ev interface{}) {
if ev, ok := ev.(*network.EventResponseReceived); ok {
if ev.Response.URL == "https://cloudflare-ipfs.com/ipfs/bafybeienieybucxgxkw6tspsjoxb5jj4kbsljbckck2e4r3pymyiilhzza/5.svg" {
wg.Done()
}
}
})
var buf []byte
// capture entire browser viewport
if err := chromedp.Run(ctx,
chromedp.Navigate("https://magic-mondrian.netlify.app/screenshot?mintAddress=0xe3bbf29f034fA780407Fd11dac7A0B3938b1bc6a&tokenId=1×tamp=1660606604&url=ipfs://bafybeienieybucxgxkw6tspsjoxb5jj4kbsljbckck2e4r3pymyiilhzza/5.svg"),
chromedp.EmulateViewport(7086, 9448),
chromedp.ActionFunc(func(ctx context.Context) error {
wg.Wait()
return nil
}),
chromedp.FullScreenshot(&buf, 100),
); err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile("fullScreenshot.png", buf, 0o644); err != nil {
log.Fatal(err)
}
} You can umcomment this line |
Thank you, but still the same behaviour. Would it be possible to implement something in the frontend that definitely tells chromedp the page has been fully finished? I would imagine some variable that is set and I am going to wait for that variable to be true or something like that? It definitely has something to do with the viewport size. When I comment out |
I tried to move the line package main
import (
"context"
"io/ioutil"
"log"
"sync"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(
context.Background(),
chromedp.WithDebugf(log.Printf),
)
defer cancel()
var wg sync.WaitGroup
wg.Add(1)
chromedp.ListenTarget(ctx, func(ev interface{}) {
if ev, ok := ev.(*page.EventLifecycleEvent); ok {
if ev.Name == "firstMeaningfulPaint" {
wg.Done()
}
}
})
var buf []byte
// capture entire browser viewport
if err := chromedp.Run(ctx,
chromedp.Navigate("https://magic-mondrian.netlify.app/screenshot?mintAddress=0xe3bbf29f034fA780407Fd11dac7A0B3938b1bc6a&tokenId=1×tamp=1660606604&url=ipfs://bafybeienieybucxgxkw6tspsjoxb5jj4kbsljbckck2e4r3pymyiilhzza/5.svg"),
chromedp.ActionFunc(func(ctx context.Context) error {
wg.Wait()
return nil
}),
chromedp.EmulateViewport(7086, 9448),
chromedp.FullScreenshot(&buf, 100),
); err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile("fullScreenshot.png", buf, 0o644); err != nil {
log.Fatal(err)
}
} |
It really works! But now I am not able to create a docker container. I can run it, but it says I am using this Dockerfile: # Start from golang base image
FROM golang:alpine
# Install git.
# Git is required for fetching the dependencies.
RUN apk update && apk add --no-cache git && apk add --no-cach bash && apk add build-base
# Setup folders
RUN mkdir /app
WORKDIR /app
# Copy the source from the current directory to the working Directory inside the container
COPY . .
# Download all the dependencies
RUN go get -d -v ./...
# Install the package
RUN go install -v ./...
# Build the Go app
RUN go build -o /build
# Expose port 8080 to the outside world
EXPOSE 8080
# Run the executable
CMD [ "/build" ] I also found this: #377 but I haven't been able to figure out how to use this. I tried this Dockerfile: # =============== build stage ===============
FROM golang:1.16.5-buster AS build
WORKDIR /app
COPY go.* ./
RUN go mod download -x all
COPY . ./
# ldflags:
# -s: disable symbol table
# -w: disable DWARF generation
# run `go tool link -help` to get the full list of ldflags
#RUN go build -ldflags "-s -w" -o screenly -v ./main.go
RUN go build -ldflags "-s -w" -o screen-api -v main.go
# =============== final stage ===============
FROM chromedp/headless-shell:93.0.4535.3 AS final
WORKDIR /app
COPY --from=build /app/screen-api ./
ENTRYPOINT ["/app/screen-api"] Then I ran: |
With this Dockerfile it works: FROM golang:1.16.5 AS build-env
RUN apt update && apt -y upgrade
RUN apt -y install chromium
WORKDIR /app
ADD ./ ./
# Download all the dependencies
RUN go get -d -v ./...
# Install the package
RUN go install -v ./...
# Build the Go app
RUN go build -o /build
# Expose port 8080 to the outside world
EXPOSE 3333
# Run the executable
CMD [ "/build" ] But now the fonts are wrong. It drives me crazy^^. One problem solved and then there is the next problem. Should look like this: But it looks like this: Not sure why, because the fonts are actually hosted by our application. |
Ok, I got the fonts working, but I have another issue. Since the actual issue is fixed, I am going to open another one. |
What versions are you running?
What did you do? Include clear steps.
I am trying to take a screenshot of a page that has some .svg content and some text and provide this functionality via REST API.
What did you expect to see?
I would expect, that the API always returns a correct screenshot with all of the content that I would expect to see.
What did you see instead?
When using
chromedp.EmulateViewport(7086, 9448)
it very often returns blank images or images where the content is cut off like the following:When I remove
chromedp.EmulateViewport(7086, 9448)
I haven't noticed any issues so far, but I am not sure if this was just luck. I need to reliably wait until everything on the screen is visible before taking a Screenshot. I don't know why it sometimes works and sometimes doesn't.The text was updated successfully, but these errors were encountered: