tsayen / dom-to-image

Generates an image from a DOM node using HTML5 canvas
Other
10.21k stars 1.68k forks source link

Bad quality with react js #332

Open da1z opened 4 years ago

da1z commented 4 years ago

Quality of png is super low.

const onGetPictureClick = () => {
    var node = document.getElementById('tweetCard');
    domtoimage
      .toPng(node, {
        quality: 0.99,
      })
      .then(function (dataUrl) {
        var img = new window.Image();
        img.src = dataUrl;
        document.getElementById('container').appendChild(img);
      })
      .catch(function (error) {
        console.error('oops, something went wrong!', error);
      });
  };
Screen Shot 2020-05-07 at 10 06 16 AM
csandman commented 4 years ago

I haven't found a guaranteed strategy to make the image as good as possible but it could be that you're using a retina screen. This comment https://github.com/tsayen/dom-to-image/issues/69#issuecomment-486146688 gives a solution that definitely improved my output image quality so you could try that. Hope it helps!

Fantasim commented 4 years ago

Got the same problem as well, just duplicate the component before screenshotting it and scale it by 3. It solved the problem.

(It doesn't come from React, it's just a scale matter)

csandman commented 4 years ago

Got the same problem as well, just duplicate the component before screenshotting it and scale it by 3. It solved the problem.

(It doesn't come from React, it's just a scale matter)

@Fantasim In that case, is the output image 3 times the size of the original as well?

Fantasim commented 4 years ago

@csandman Yes, it is.

Here is my code.

const scale = 3    
const node = document.getElementById("post")

const style = {
    transform: 'scale('+scale+')',
    transformOrigin: 'top left',
    width: node.offsetWidth + "px",
     height: node.offsetHeight + "px"
}

const param = {
     height: node.offsetHeight * scale,
     width: node.offsetWidth * scale,
      quality: 1,
     style
}

domToImage.toJpeg(node, param)
akshaybosamiya commented 4 years ago

@csandman Yes, it is.

Here is my code.

const scale = 3    
const node = document.getElementById("post")

const style = {
    transform: 'scale('+scale+')',
    transformOrigin: 'top left',
    width: node.offsetWidth + "px",
     height: node.offsetHeight + "px"
}

const param = {
     height: node.offsetHeight * scale,
     width: node.offsetWidth * scale,
      quality: 1,
     style
}

domToImage.toJpeg(node, param)

Value of scale can be calculated dynamically. var scale = Math.min(node.offsetWidth/contentWidth, node.offsetHeight/contentHeight); Where contentWidth and contentHeight are actual width and height of Image area.

jrmarqueshd commented 3 years ago

I was the same problem of the @da1z, and the solution suggested by @Fantasim solved.