New issue
Advanced search Search tips

Issue 906386 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Nov 19
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug



Sign in to add a comment

SVG converted to image to draw on canvas has bad size

Reported by d3c...@gmail.com, Nov 17

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36

Steps to reproduce the problem:
I created a single HTML page gist here...
https://gist.github.com/d3x0r/d19713181850cae0e524030a537988b5
And a JSFiddle of the same here http://jsfiddle.net/d3x0r/g9docs3f/1/

1) create a canvas sized 600x600
2) create an svg
3) get SVG HTML to set as Image data URI, of an image of size 100x100. (or 0x0, assuming the rendering of the SVG will set a Width/height, which it does not)
4) output image to canvas

What is the expected behavior?
The image output to the cavnvas is drawn as if the image is the size of the canavs, not the size of the image it came from.

How this shows as an issue, I draw only tiled portions of the image, and need to know the size of the image in order to slice it into tiles to output.  If I use the size of the image with Data URI, then it's only 100x100, and the total grid only covers a portion of the image drawn to the canvas.
If I draw the same image to a diffrent canvas with a different size, the image id rawn as if it is a different size, making all tile calculations invalid.

I started using the canvas size as the image size to slice to pass the coordinates for ctx.drawImage( image, sx, sy, sw, sh, dx, dy, dw, dh ) which works for Chrome, but it looks like other browsers are going to output the Image as the size of the image I specified, and not the size of the canvas.

What went wrong?
The size of the canvas is used as the image source size.

There is a difference in the returned svg.outerHTML, in that the tags returned from chrome do not include the xmlns='http://www.w3.org/2000/svg"  as would actually be required to render the image....

The example code was written for/on chrome, so it has a fix for insertting the XMLNS= on the SVG element.

so I have 2 issues
1) svg.outerHTML should include xmlNS=
2) the image drawn to the canvas should be the size of the image and not ht esize of the canvas.

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 69.0.3497.100  Channel: n/a
OS Version: 10.0
Flash Version: 

( Firefox doesn't draw the image at all into the canvas.
Edge draws part of the image, but the image is sized to the image part).

My actual application https://d3x0r.org/javascript/bugbrain
 
I updated the test case, http://jsfiddle.net/d3x0r/g9docs3f/3/ 
and the gist, to set svg attribute width and height.
This makes chrome draw the image as the expected size, instead of the canvas size.

Is still an issue that outerHTML doens't include xmlns of svg elements.
Chrome Canary renders your first jsfiddle just like Firefox.
The change occurred somewhere in https://chromium.googlesource.com/chromium/src/+log/f888d68b..0cb77ba1
To pinpoint the exact CL a per-revision bisect is required.
When you sayd 'just like firefox' you mean 'not at all'

(attached firefox screenshot that shows only black rect in canvas, not image from SVG)

After fixing svg.setAttribute("width",66) instead of svg.stile.width = 66... chrome draws image small upper left corner... and has expected size. (second screenshot)  

firefox-fiddle.jpg
114 KB View Download
chrome-fiddle.jpg
86.1 KB View Download
Labels: Needs-Milestone
Regarding that patch list there's a note about # beginning URI?  The Encode URI doesn't seem to encode some # in the SVG... I have seen warnings about using that.... 


:url("#gradient-2n")


adding 

  svghtml.replace( /#/g, "%23");   

migth fix that..   http://jsfiddle.net/d3x0r/6yvkcw9b/17/ (updated)



Cc: phanindra.mandapaka@chromium.org
Components: Blink>SVG
Labels: Triaged-ET Needs-Feedback
Thanks for the issue...

Tried to reproduce the issue on reported chrome 69.0.3497.100 and latest chrome stable 70.0.3538.102. Attaching screencast for reference.
Steps:
-----
1. Launched chrome 
2. Navigated to given jsfiddle > http://jsfiddle.net/d3x0r/6yvkcw9b/17/
As we have observed that the jsfiddle rendering in both chrome and firefox same.

@Reporter: Could you please check the attached screen cast and let us know if anything missed from our end and verify this on latest stable, you can download latest chrome builds here:" https://www.chromium.org/getting-involved/dev-channel "

Thanks..!
906386.mp4
4.3 MB View Download
Status: WontFix (was: Unconfirmed)
1) xmlns

Since you don't specify any 'xmlns' attribute, none will be serialized. Note that you're using HTML serialization functions, and in HTML no 'xmlns' is required for <svg> to get the correct namespace. Consider using XMLSerializer.serializeToString or simply add the attribute explicitly. The former would be the safer way in general for something that is supposed to be an XML serialization (since it will handle other cases, like XLink, too).

2) sizing on <canvas>

For the case with no intrinsic width/height (like here with the case without width/height attributes), it's specified that the size of the output bitmap is used as an input to compute the concrete object size, which is then used as the source and destination rectangles:

  "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:dom-context-2d-drawimage-3)

So in your case, it'd probably be a good idea to specify a destination width and height to drawImage(). (I.e use the 5 argument version of the function.)
It's fine that this is a won't fix.

though re 1) the SVG is created with var svg = document.createElementNS( "http://www.w3.org/2000/svg","svg" );  which has a xmlns.  The more widely supported method is to use XMLSerializer.  using outerHTML doesn't retrun xmlns, and encodes elements like <circle .../>  as <circle ...></circle>; the later format into img.src doesn't work all over.  (does for chrome, if I insert xmlns= in the svg element)

2) ya I understand the 'failure' there.

I was drawing with the 9 parameter drawImage, the problem was, I needed consistent spacing to get the source x/y,w/y; which is acheivale setting width and height attributes.


jsfiddle.net/d3x0r/6yvkcw9b/28/ 
This version works the same in chrome(should work in canary also with '#' substitution) and firefox. Edge draws some of the gradients as black, and safari renders the gradients too light, making it all near white.
"has namespace" != "has 'xmlns' attribute" (even regular HTML elements have a namespace, but will definitely serialize without an 'xmlns'). 'xmlns' really only serves a purpose for parsing (and thus indirectly for serialization so that round-trips are possible), but since the HTML parser decides the namespace using the tag name, the 'xmlns' is not needed in an HTML context.

Sign in to add a comment