question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generating a Blank Image in Safari Browser

See original GitHub issue

This package is generating a blank image in the Safari browser but it’s working good in Chrome and Firefox

Expected Behavior

It should work as good in Safari as well, as it is working on Chrome and Firefox

Current Behavior

Generating a blank image in Safari

Your Environment

  • html-to-image: 1.9.0
  • OS: Big SUR (M1 Macbook)
  • Browser: Safari 14.1.2

Code

  const onSaveClick = async () => {
    try {
      const avatar = document.querySelector("#avatar") as HTMLElement;
      const image = document.querySelector(".traitLayer") as HTMLElement;
      if (avatar === null) {
        return
      }
      const imageConfig = {
        cacheBust: true, pixelRatio: 1, height: image.clientHeight, quality: 0.98,
        width: image.clientWidth, canvasWidth: 3000, canvasHeight: 3000,
      }
      const dataUrl = await toPng(avatar, imageConfig)
      const link = document.createElement('a')
      link.download = 'Avatar.png'
      link.href = dataUrl
      link.click()

    }  catch (err: any) {
      // Nothing here
    }
  }

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:8
  • Comments:19 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
hlmartincommented, Feb 23, 2022

Building off what @vince760 and @GeekyADAMS posted, I came up with this solution which will check the top left and bottom right pixels and retry until they differ. Obviously, this works best when the image you are rendering doesn’t have solid colours around the outside, however if you adjust the max attempts you might be able to catch this without wasting too much time.

function safariDownload(attempts) {
  const element = document.getElementById('Element you are wanting to download');
  htmlToImage.toCanvas(element).then(function(canvas) {
    const context = canvas.getContext('2d');
    const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
    if (!pixelsAreEqual(imageData) || attempts >= 10) {
    canvas.id = *Give your canvas an ID*;
    document.body.appendChild(canvas);
    canvasToImage('Name of the canvas ID you assigned on canvas.id', {
       name: `Name you want given to the image hen downloaded`,
       type: 'png',
       quality: 1,
     });
     document.body.removeChild(canvas);
    } else {
      console.log(`Trying Safari rendering again (attempt #${attempts + 1})...`);
      setTimeout(() => (safariDownload(card, options, attempts + 1)), 1000);
    }
  });
}

function pixelsAreEqual(imageData) {
  const len = imageData.data.length;
  const topLeftPixelRgba = [imageData.data[0], imageData.data[1], imageData.data[2], imageData.data[3]];
  const bottomRightPixelRgba = [imageData.data[len - 4], imageData.data[len - 3], imageData.data[len - 2], imageData.data[len - 1]];
  return (topLeftPixelRgba.every((v,i)=> v === bottomRightPixelRgba[i]));
}
3reactions
branlokcommented, Oct 13, 2021

For me as well, both Firefox and Safari was behaving differently from from expected behaviour in Chrome. The snapshot I try to create would not include the background images of a div whether they are local or external image URL. However, when I manually use the equivalent of your onSaveClick the second time, it would correctly generate my target div with the expected background images.

I tested with duplicating this bit of code, discarding the first generation, and take the second. This workaround actually fixes Firefox. However, Safari seems to still be the same.

      const imgBase64_dump = await toPng(captureRef.current, {
        quality: 0.01,
        pixelRatio: 1,
        height: captureRef.current.scrollHeight,
        canvasWidth: captureRef.current.scrollWidth,
        canvasHeight: captureRef.current.scrollHeight,
      });

      const imgBase64_again = await toPng(captureRef.current, {
        quality: 1,
        pixelRatio: 1,
        height: captureRef.current.scrollHeight,
        canvasWidth: captureRef.current.scrollWidth * 2,
        canvasHeight: captureRef.current.scrollHeight * 2,
      });

      download(imgBase64_again, "generated.png", "image/png");

Read more comments on GitHub >

github_iconTop Results From Across the Web

Create a disk image using Disk Utility on Mac - Apple Support
In the Disk Utility app on your Mac, choose File > New Image > Blank Image. · Enter a filename for the disk...
Read more >
How do I start a new blank image page in Preview?
Double click on the image, which should open it in Preview as an image: image in preview; Print the image (command-P); Save it...
Read more >
Image doesn't show in Safari browser - Stack Overflow
It's possible that you simply haven't cleared your Safari cache. Try holding SHIFT while clicking on the refresh icon. – Obsidian Age. May...
Read more >
CanvasRenderingContext2D.createImageData() - Web APIs
colorSpace : Specifies the color space of the image data. ... Creating a blank ImageData object ... Safari on iOS. Samsung Internet.
Read more >
How to create blank icons for your iPhone Home Screen
1) Tap and hold any empty area on your iPhone Home Screen to enter wiggle mode – the mode when all app icons...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found