Canvas drawimage error scale svg
Categories
(Core :: SVG, defect, P3)
Tracking
()
People
(Reporter: matias.kenig, Unassigned)
Details
Attachments
(2 files, 1 obsolete file)
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36
Steps to reproduce:
1-open "test.htm"
2-wait to load the "test.svg" image.
3-look the result image scaled (its a bug),
4-compare with google chrome
Actual results:
The loaded svg IS NOT scaled into canvas
Expected results:
the loaded svg image MUST be scaled into canvas
Comment 1•5 years ago
|
||
Comment 2•5 years ago
|
||
Updated•5 years ago
|
Comment 3•5 years ago
|
||
In this particular case the SVG has a viewBox and therefore an aspect ratio. We probably shouldn't allow canvas to override that. Our rendering is probably correct here. However I haven't checked what happens if the viewBox is removed.
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 5•5 years ago
|
||
Hi Amelia, do you know if our behavior here is supported by the SVG and HTML specs, or if we need to add some wording?
Comment 6•5 years ago
|
||
I don't think we have any specs that specifically talk about the intersection of SVG and canvas contexts. However, my expectation is that you would get the same rendering as if you drew the SVG as an HTML img with the specified width and height (750×200).
SVG was always defined in a way that worked for embedding in any rendering environment. The initial scale is determined by the rectangle the outer rendering system gives the SVG to draw itself in, regardless of how that rectangle is specified in the outer layout language. When such a rectangle is specified, it overrides the width and height attributes on the root element of the SVG file. Those attributes are only used as defaults for when the outer environment allows the embedded image to specify its own size or aspect ratio.
Since the SVG file specifies a square viewBox and doesn't specify a preserveAspectRatio behavior, I would expect the square aspect ratio to be maintained, with the image scaled to meet the rectangle given. I'd also expect the non-scaling-stroke
to be respected (relative to the 750×200 dimensions: if you scale the canvas itself, that's another matter).
In other words, IMO, Firefox behavior is correct, Chrome behavior is buggy.
However…
Reading the current text of the SVG 2 spec, it's not so clear that this is true.
SVG 2 reference are the sections "The initial viewport" and "Intrinsic sizing properties of SVG content" in the Coordinates chapter: https://svgwg.org/svg2-draft/coords.html
Compare with the SVG 1.1 version of the same sections: https://www.w3.org/TR/SVG11/coords.html
In trying to be explicit about how SVG interacts with CSS layout, I think the wording has been made a little too specific for CSS layout, by talking specifically about HTML embedded objects and CSS-compatible properties on them. The current reading doesn't allow for non-CSS rendering environments (such as canvas drawImage()
commands, or even CSS background image sizing) to override the default width and height on the SVG. In contrast, the SVG 1.1 version of the spec is much more general, and applies to any external layout constraints.
I am not aware of any intentional reasoning for this change, so I've filed a bug on the spec: https://github.com/w3c/svgwg/issues/762
In the meantime, if anyone does want the Chromium behavior:
You can get most of the way there by adding preserveAspectRatio="none"
on the <svg>
element in the file. That will cause the viewBox to stretch to whatever aspect ratio you give it. However, Firefox will still render the SVG at the pixel size you specify, and will properly maintain the non-scaling-stroke despite the stretched scale.
To completely replicate the Chromium behavior, you would need to draw the SVG image to a temporary canvas at its natural width and height, then use that bitmap rendering as a separate image input to the drawImage function with the distorted dimensions. (This is similar to a popular performance trick used to pre-render a batch of canvas API commands that you want to then reuse like an image sprite.)
Comment 7•5 years ago
|
||
I think our implementation makes sense. Hopefully the SVG 2 specification will change back given that its current change seems somewhat unintentional.
Description
•