canvas context.drawImage differences across browsers?
Asked Answered
A

1

7

I'm facing a really bizarre issue when trying to scale and crop an image using the HTML5 canvas API across browsers.

Specifically, I'm working with trying to find the center of an image and crop a square based on its width and height using these parameters as specified by the context API

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

Here's an example of the code I'm using:

<!DOCTYPE html>
<html>
<body>

<p>Image to use:</p>
<img id="scream" width="220" height="277" src="img_the_scream.jpg" alt="The Scream">

<p>Canvas:</p>
<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>
window.onload = function() {
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var img = document.getElementById("scream");
    ctx.drawImage(img, 0, 25, 220, 277, 0, 0, 150, 188);
}
</script>

</body>
</html>

You can try the demo here: http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_canvas_drawimage2

The code does not display anything on the canvas in Safari, however it correctly scales and crops the images in Chrome.

I would upload images but stackoverflow has an arbitrary rule that doesn't allow me to post images until I have a higher reputation!

Any thoughts here would be appreciated!

Anhwei answered 14/4, 2015 at 17:6 Comment(1)
Here are links to the two images: Safari: cl.ly/image/3e051H2s2l0b Chrome: cl.ly/image/2M3H2J1U0X15 Again, I can't add them to the post, because I don't have enough reputation.Anhwei
R
7

The problem in Safari could be sensitivity to source size, the region you specify as source versus available bitmap.

For example, the source in the example says:

//        source:  x, y , w  , h
ctx.drawImage(img, 0, 25, 220, 277, ...

This will mean the bitmap has to be 25+277 pixels in height which of course is not the case as the input image is only 277 pixels in height.

Try adjusting source region to be inside the image, in this case reducing height with y offset:

ctx.drawImage(img, 0, 25, 220, 277-25,   0, 0, 150, 188);

To crop always make sure the source region is inside the image, f.ex. if you want to crop 10 pixels in from all sides:

var iw = img.naturalWidth;
var ih = img.naturalHeight;
var crop = 10;

ctx.drawImage(img, crop, crop, iw - crop*2, ih - crop*2, 0, 0, 150, 188);
Redeeming answered 14/4, 2015 at 17:25 Comment(1)
Ah, that did it! I just had to reduce the height by the offset I created $ ctx.drawImage(img, 0, 25, 220, 252, 0, 0, 150, 188); and that worked. Thank you!Anhwei

© 2022 - 2024 — McMap. All rights reserved.