Very large SVG rendered blurry in Firefox - html

I'm trying to render a very large SVG image inside an img tag.
This works fine in Chrome, but Firefox (both Windows and Linux) renders the image blurry as if it was a raster image with much lower resolution.
The problem can be broken down to a simple example:
SVG image with a view box of 30,000x30,000, showing a diagonal line
The SVG is displayed in an img tag that has a width and height of 30,000px each
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30000 30000'%3E%3Cpath d='M 0,0 L30000,30000' stroke-width='1' stroke='%23000' /%3E%3C/svg%3E" width="30000" height="30000" />
This renders as follows (cropped but not scaled):
What I already tried unsuccessfully:
different view box sizes
smaller img dimensions but scaled up with CSS transforms (2D/3D)
image-rendering: crisp-edges on the img
shape-rendering: crispEdges on the SVG content
Using an <object> instead of an <img> actually renders the image crisp, but the <object> element comes with its own shortcomings and pitfalls. If possible I'd like to keep using the <img> element.
Does anybody have hints what might be the problem or ideas for possible solutions?

Related

Gap in vertical repeat of svg background

I have a simple div, with an SVG set as background image with vertical repeat. On Chrome and Firefox, depending on the screen size, I see a gap in varying sizes (please resize the window).
https://jsfiddle.net/bartadaniel/ejtvy7po/9/
.bg {
width: 50%;
height: 2000px;
display: block;
background-repeat: repeat;
background-size: contain;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='272' height='171' viewBox='0 0 272 171'> <rect class='cls-1' width='272' height='171' fill='green'/></svg>");
}
<div class="bg"></div>
Is there a reason for this?
That's happening due to a combination of background-size:contain and the pixel dimensions of your svg.
You're seeing the browser try to scale the image so that nothing overflows the bounds of your <div>. When you combine that scaling with image pixel dimensions of 171 (can't be evenly multiplied into 2000px) you get lines showing you the sub pixels you're browser is trying to display.
Simply remove the background-size:contain to solve it.
Edit:
In the case where you need to contain width, there are a few tricks to help get a better result.
Make the background image dimensions multiples of 10. Square would be best with something like 100x100px but it could also be a rectangle (try to get close to your target width) like 1000x100px.
Set background-size: 100% auto instead of contain. This will stretch the image proportionalty to fill the container width.
Use background-repeat: repeat-y to force a vertical repeat so the browser is only doing the math on one axis.
It is a problem of subpixel rendering.
Each browser rounds differently and SVG subpixel rendering is pretty messed up.
I suggest you to edit your SVG content to make it slightly bigger than your viewbox.
<svg xmlns='http://www.w3.org/2000/svg' width='272' height='171' viewBox='0 0 272 171'>
<rect class='cls-1' y='-.5' width='272' height='172' fill='green'/>
</svg>
Obviously this trick doesn't work for all the background SVG, but might be useful in your case.
Unfortunately, the only solution that reliably tackled this issue was to convert the SVG to a pixel-based format, like JPG. Apparently, the browsers have no problem scaling pixels but causes side effects at edges when scaling vector-based formats.
If your SVG will still look acceptable with less anti-aliasing, you can change the anti-aliasing of the shapes in your SVG using the shape-rendering property. Example:
<rect shape-rendering="crispEdges">
You can use this on these elements: <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, and <rect>.

Base64 svg on ie11 not rendering when resized

I have a particular svg file encoded in base64 that I'm trying to display with an img tag.
My problem is; for this particular svg only the image is not rendered when resized on internet explorer only
You can try it yourself (I'm on windows7 with ie11): CodePen
Do you have any explanation/workaround for this ?
Best regards
If you look very close when playing with the size, we can see parts of the SVG are actually displayed. It seems that IE resizes the canvas but not the actual shape.
Decoding your SVG file, here is what we get:
<svg height="361.5" width="361.5" xmlns="http://www.w3.org/2000/svg"><path d="m-110.25-20.25h582v402h-582z" fill="none"/>...</svg>
The height and width are fixed. Changing these properties with a viewBox property like this allows IE to resize the shape:
<svg viewBox="0 0 361.5 361.5" xmlns="http://www.w3.org/2000/svg"><path d="m-110.25-20.25h582v402h-582z" fill="none"/>...</svg>
Kind regards!

SVG opacity mask resolution and scaling

I'm trying to reduce the download size of transparent PNGs by decomposing them into color and alpha images. This approach works fine, for my customer's images the size is reduced by over 50%.
To recompose the images I'm experimenting with both SVG and canvas.
The SVG solution uses an opacity mask, and the canvas uses the globalCompositeOperation.
The problem is, the SVG incorrectly shows dark edges when down-scaling (either by specifying the size in CSS or directly on the SVG). These dark edges do not appear when rendering the SVG at the same size of the input images. The canvas works fine. This happens in all browsers I tested (Chrome, IE11, Firefox)
The problem I believe, is that the SVG will independently resize the alpha-image and color-image, and then apply the opacity mask. However this approach does not work. In image processing it is well known that to resize a transparent image, one either has to pre-multiply the color components by the alpha, and then use a standard resizing algorithm, or one has to perform a weighted average (since mostly transparent pixels have less impact on the final color). See for example this discussion
When applying SVG filter effects, one could initially tweak the intermediate resolution that is used, but I can't figure out how to do this when using the SVG mask property (Robert Longson correctly pointed out to me that the filter effects do not support this anymore, since the filterRes attribute was deprecated)
Here's the SVG code (our run it directly from my website in any HTML5 compliant browser)
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='1000' height='454' viewBox='0 0 2560 1162'>
<defs>
<mask id='mask'>
<image color-interpolation='sRGB' image-rendering='optimizeQuality' width='2560px' height='1162px' xlink:href='first-A.png'></image>
</mask>
</defs>
<image color-interpolation='sRGB' image-rendering='optimizeQuality' mask='url(#mask)' width='2560px' height='1162px' xlink:href='first-RGB.png'></image>
</svg>
Does anyone know how to tweak the SVG mask effect so that these edge artifacts do not appear?
Thanks a lot,
Peter

SVG CSS | SVG only works in chrome

Having issues with an SVG I have made.
It works great in chrome and does exactly what i want and expect it too but I cannot get it working in any other browser (tried IE and Firefox so far).
My SVG is an image with a clip path cutting it out into the shape I want and this works on different resolutions spanning the full page width. Below is how it looks in chrome including an image of when the page width expands
The html for the SVG looks as follows
<svg id="mobile-svg" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 875.67 321.8" preserveAspectRatio="none">
<defs>
<style>.cls-1{fill:#60b6e1;}</style>
</defs>
<clipPath id="myClip">
<path d="M0,0S1,7.68,12.63,18.54,364.25,297.4,364.25,297.4s30.77,27.3,84.06.38,379.59-192,379.59-192S873.34,87.5,875.67,0H0Z" transform="translate(0)"></path>
</clipPath>
<image class="cls-image" xlink:href="http://localhost:63342/Carfinance247Rebrand/Content/img/carDrivingImage.png" clip-path="url(#myClip)"/>
</svg>
The CSS for the SVG (.SCSS)
#mobile-svg {
margin-bottom: -3px;
background-color: #5fb6e0;
.cls-image {
width: 100%;
height: 115%;
}
}
All works in chrome as expected but see image below for Firefox, the same thing also happens in IE (version 9 - 11)
I have tried changing position types and display types, also setting set width and ehights but cant get it to appear in other browsers.
I ahve an SVG that uses clip paths at a different point in the page and this one works fine, hence the confusion for this one. See image below of my working SVG
inb4 I am relatively new to SVG's
In SVG 1.1 an <image> element must have height and width attributes i.e. you can't set the height and width via CSS.
In SVG 2 it is proposed that image elements have width and height that are CSS properties.
Only Chrome has so far implemented this part of the SVG 2 specification.

IMG tag with external SVG file not responsive to scaling of container

This is a commonly asked question (and I have looked for, found and tried a variety of other suggestions, here on stackoverflow and elsewhere)
I have an web page where I'd like to dynamically load in maps, which are in SVG format. I would like the maps to be responsive to rescaling of their container, i.e. fill the width of the container as the window resizes for example.
<div class="container">
<img src="http://snacknack.com/1/08.svg" style="height: 1286px;" />
</div>
The external 08.svg file starts like this:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 909 1286">
Instead of resizing the SVG remains rock solid at its original size. Here is the jsfiddle (Note: viewbox edited to viewBox in svg file thanks helderdarocha for spotting that)
I have tried giving the .container a width:100%, height:100%; but that does not work, nor do various other suggestions for related questions. I am not sure whether that is because I have to use an external file to provide the SVG (rather than doing the SVG inline which is what examples do) or
whether it is because of something inside the SVG content.
I have already tried using an OBJECT tag to bring in the SVG file rather than an IMG tag. Same issue.
If I do not provide the hardcoded height in the IMG tag, the map will truncate at around 377-400px vertically (in my Mac OS Chrome & Safari browsers) and if I set it to height:100% the map disappears entirely.
How do make this IMG tag/SVG responsive ?