When scaling and drawing an image on a canvas in Safari iOS, the width is correct, but the height is compressed

I upload an image and then draw this image onto the canvas. I also scale the image down to fit the canvas. When I do this, the image is drawn on the canvas with the appropriate width, but the height is about 1/4 of the actual height of the canvas.

//Calculate height from canvas-to-image width ratio var width = canvas.width; var height = ( width / img.width ) * img.height; //Draw scale image (This results in a squished height, despite "height" being correct) context.drawImage( image, 0, 0, img.width, img.height, 0, 0, width, height ); 

Even if the height correct (marked on the console), the image draws on the canvas at a much lower height.

Also, when I check the canvas.width / canvas.height vs img.width / img.height , I get: .707234 vs .707818 . . It is so close that it can not cope with the problem of great height.

Why is this happening? How to fix it?

EDIT: In Chrome, this exact code displays correctly.

+1
source share
2 answers

This is a bug in Safari iOS. Described here: Mobile Safari displays <img src = "data: image / jpeg; base64 ..." β†’> scaled on canvas?

The solution is here: https://github.com/stomita/ios-imagefile-megapixel

Problem

If you have an image with a very high resolution (greater than 1024x1024), it will be a subsample (reduces the number of pixels by 16x). At the same time, Safari introduces an error that leads to a too low vertical height.

Decision

To solve this problem, you take small fragments of the image (for example, reading from a file into the buffer in pieces), adjust the vertical differential in height, draw only those that are on a temporary canvas, and then draw this temporary canvas' pixels on the destination canvas.

+1
source

var ratio = (width / img.width) * img.width; will leave the ratio equal to the width and don’t learn anything from img.width, since you are deleting the division by multiplying by the same value. This will ruin your height calculation, which will ruin the drawn image.

Try the following:

 var ratio = ( width / img.width ); 

And you get the real ratio between canvas and image height. But I don’t think you want it.

What you want is to keep the aspect ratio (width / height) of your image the same and reduce its size. This is possible even if the canvas has a different aspect ratio, leaving unused space on the sides, top or bottom.

So, you really need to know what you should use to scale the image. Width or height.

If the image has a larger aspect ratio than the canvas, then scale using the width. This means that the width will be the same and set the height for any aspect ratio. This will cause the upper and / or lower spaces to be omitted.

If the image has a lower aspect ratio than the canvas, then scale using the height. Blah blah, the height is the same. The width of the scale. Blah blah blanks on the sides.

 var imgRatio = img.width / img.height; var canRatio = canvas.width / canvas.height; var scaledWidth = img.width * (canvas.height / img.height); var scaledHeight = img.height * (canvas.width / img.height); if (imgRatio > canRatio) { context.drawImage( image, 0, 0, canvas.width, scaledHeight ); } else { context.drawImage( image, 0, 0, scaledWidth, canvas.height ); } 

In addition, if you do not crop the image, use only scaling, then you need all these parameters.

http://www.w3schools.com/tags/canvas_drawimage.asp

+1
source

All Articles