drawImage changed behaviour on 100% dimensions SVGs
Reported by
andreabo...@gmail.com,
Nov 26 2017
|
||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:58.0) Gecko/20100101 Firefox/58.0 Steps to reproduce the problem: 1. open https://jsfiddle.net/cb1utxwm/5/ on chrome 51 or newer 2. open https://jsfiddle.net/cb1utxwm/5/ on chrome 50 or lower 3. observe the SVG is drawn differntly on canvas What is the expected behavior? There is no expected behaviour to be honest. The specs says that an svg with no width/height should be drawn at 100% of its container dimensions. There is no container in this case and what chrome always did, aligned with safari, was to fit the SVG in the naturalWidth/naturalHeight box at 300x150. After chrome 51 it looks like that the canvas is taken as a container for the image and the SVG is drawn at 100%. The problem is that the image element width/height are still considered to be 300x70 on the element. What went wrong? What is wrong? The image is drawn bigger than the reported width/height. drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) can't be used anymore with predictable results since from the img element we cannot understand what is the real width ( is 100% but we have no clue from outside ) so tring to use `sx, sy, sw, sh,` will give us different results based on canvas size. Did this work before? Yes chrome 50 Does this work in other browsers? N/A Chrome version: 51.0.2704.106 (64-bit) Channel: stable OS Version: OS X 10.12 Flash Version:
,
Nov 26 2017
Here a similar fiddle with the 9 args version of drawImage https://jsfiddle.net/cb1utxwm/7/ As you can see till the canvas is smaller than the SVG 300 px naturalWidth everything could look fine, but as soon as the canvas is bigger, we start to loose pieces of the image. And again we have no way to understand that the image will be drawn bigger than what img.width says.
,
Nov 27 2017
,
Nov 27 2017
"Establish the source and destination rectangles as follows: If not specified, the dw and dh arguments must default to the values of sw and sh, interpreted such that one CSS pixel in the image is treated as one unit in the output bitmap's coordinate space. If the sx, sy, sw, and sh arguments are omitted, then they must default to 0, 0, the image's intrinsic width in image pixels, and the image's intrinsic height in image pixels, respectively. If the image has no intrinsic dimensions, then the concrete object size must be used instead, as determined using the CSS "Concrete Object Size Resolution" algorithm, with the specified size having neither a definite width nor height, nor any additional constraints, the object's intrinsic properties being those of the image argument, and the default object size being the size of the output bitmap." (https://html.spec.whatwg.org/multipage/canvas.html#drawing-images) The interesting bit being: "...the default object size being the size of the output bitmap." where "the size of the output bitmap" is the size of the canvas backing store as defined by the 'width' and 'height' attributes on the canvas element.
,
Nov 27 2017
Ok so reading the canvas spec it looks like this is a bug it has been solved in chrome 51 vs chrome 50. But how i m supposed to know i m dealing with an image that has no `intrinsic dimensions`? you are assigning 300 and 70 to the image, that is the SVG fitted in 300x150, but no flag is given that says `no intrinsic dimenions` also it looks like that if i want to set the img width and height i get no different result. And also i ask you which is the logic in assigning an image element a 300x70 dimensions. How a developer should handle those kind of svgs? does the spec give any help? Firefox for example do not assigns 0 to it and refuse to render it. Is theyr a bug then?
,
Nov 27 2017
Able to reproduce the issue on reported version 51.0.2704.106, latest canary 64.0.3278.0, stable 62.0.3202.94 using Mac 10.12.6, Ubuntu 14.04 and Win10 hence providing bisect info Bisect Info: ================ Good build: 51.0.2671.0 Bad build: 51.0.2672.0 CHANGELOG URL: https://chromium.googlesource.com/chromium/src/+log/17ecedac5929c7d94f98ba6ca2385686281facda..af53e933f2546527a7ee02f21eefb2f59f41fc8b suspect:https://chromium.googlesource.com/chromium/src/+/c1bb9d9096de137378cb1029021aed40fcbf76e4 Suspecting same from changelog. @fs: Could you please check whether this is caused with respect to Author: Davve@ change, if not please help us in assigning it to the right owner Thanks!
,
Nov 27 2017
img.naturalWidth/Height is supposed to return the intrinsic dimensions. They currently don't always do that in Blink, but that is a bug. Currently what's returned is the concrete object size resolved with 300x150 as default object size, which because of the viewBox (i.e the intrinsic aspect ratio) yields a width of 300 and a height of 300 / (191 / 44.5) ~= 70. img.width/height has no effect when the image is used on a <canvas>. The way to deal with images without intrinsic width/height is usually to define an area for them to paint in - i.e pass a full destination rectangle to drawImage (using the 5 arg version.) Firefox does appear to have a bug since they don't use the canvas size to resolve the concrete object size.
,
Nov 27 2017
Can we count at least on having the 300/150 with correct aspect ratio to be defined somewhere? Or since the intrinsic dimensions are not define naturalWidth and naturalHeight should be undefined too? But still the 9 arg version is not usable, is this by definition or is something that at some point should be solved?
,
Nov 27 2017
naturalWidth and naturalHeight are defined to return 0 for these cases [1]. For an <img> without 'width' and 'height' attributes, the 'width' and 'height' properties will return aspect corrected dimensions (based on available width, when in the document.) Specifying a source rectangle needs to consider the canvas dimensions. I guess something like "img.naturalWidth || canvas.width" (similarly for height) would work (if naturalWidth et.c worked.) [1] https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalwidth
,
Nov 27 2017
Well but the AR still play a role, i have no idea if the image is wide and tall and so if i should consider canvas width or canvas height as fixed dimension. So in this case the bug is that naturalWidth and naturalHeight should return 0. a 0 dimension for an image is an acceptable warning that there are not intrinsic dimensions. Still the AR is missing then to give a developer the chance to do something that makes sense. Am i correct?
,
Nov 27 2017
Exposing the aspect ratio in some way would probably not be a bad idea, but that needs spec changes before we can do anything about it.
,
Nov 29 2017
I've filed issue 789511 about the incorrect values returned by naturalWidth/naturalHeight. I'd suggest that an issue is raised on the WHATWG GitHub (https://github.com/whatwg/html/issues) about exposing the aspect ratio of the image referenced by an <img>. I'm resolving this as WontFix, because the behavior is both "as intended" and "per spec", although granted interop appears to be poor in this area.
,
Nov 29 2017
Makes sense. I wonder how longer will take for browser to align. I think parsing the SVG and inserting some width/height sniffing the viewbox is the only safe option here for a developer that wants to handle the images safely. |
||||
►
Sign in to add a comment |
||||
Comment 1 by andreabo...@gmail.com
, Nov 26 201758.2 KB
58.2 KB View Download
101 KB
101 KB View Download