Stop auto image smoothing inside an SVGZ - html

I'm using SVGZ images on HTML pages for their resizability. These SVGZ images contain PNGs that have been enlarged in specific ways that I want to preserve, pixelation and all. Firefox is displaying this correctly (the way I designed it in Inkscape):
while Chrome is "helpfully" autosmoothing everything:
I'm teaching a course, and I'm trying to show how image data is being created over successive passes. I want the pixelation, because that's what the data is. In fact, the PNGs inside the SVGZ contain the property style="image-rendering:optimizeSpeed". I was hoping that Chrome would recognize that and respect it.
(Please note that I've already tried the CSS image-rendering: pixelated; trick. I'm sure that would work perfectly well if I were showing PNGs directly, but that's not what I'm doing.)

Works for me in Chrome:
<svg width="100" height="100">
<image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFElEQVQIHWP4z8DwHwyBNJDN8B8AQNEG+t5Ik2kAAAAASUVORK5CYII=" width="100px" height="100px"/>
</svg>
<svg width="100" height="100">
<image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFElEQVQIHWP4z8DwHwyBNJDN8B8AQNEG+t5Ik2kAAAAASUVORK5CYII=" width="100px" height="100px" style="image-rendering: pixelated"/>
</svg>

I found an answer that builds on what Paul said above.
It looks like the way to do this in Chrome is to make sure that the PNG inside the SVG/SVGZ has the property style="image-rendering: pixelated", which makes sense. However,
This doesn't work with Firefox.
This isn't an option within Inkscape, so if you want it you have to edit the SVG code manually.
Both Firefox and Inkscape seem to prefer style="image-rendering: optimizeSpeed". So I ended up adding both to my SVGZ file: style="image-rendering:optimizeSpeed;image-rendering:pixelated". This seems to make both browsers happy, though again it means modifying the SVG code of the image file manually, since Inkscape doesn't let you do it directly.
I'm going to add an Inkscape tag if I can, since this seems to involve that program as much as anything.

Related

HTML-only fallback for MathML

MathML is a web standard for writing mathematics in a way that can be easily zoomed without pixellating (just like SVG), copied and pasted, and read by screen readers.
Chrome are refusing to implement it on the basis that a JavaScript polyfill exists. (I kid you not.) Edge's support is 'Not currently planned'. Thus, it's just Safari and Firefox (and some EPub readers) that support MathML.
Given that implementation is so spotty, fallback content is 100% necessary. The usual solution for this is MathJax; but this doesn't work for users who have JavaScript disabled or, more likely, broken.
We live in an age where HTML easily allows fallback content without JavaScript (see the <picture>, <audio> and <video> tags). Is there some way to do so for MathML?
As far as I am aware, there is no HTML-only way to detect support for MathML.
However, there is an SVG way.
The <switch> SVG element renders the first direct child of itself where certain boolean attributes on that child are either missing or evaluate to true. One such attribute is the requiredExtensions attribute, which mandates that the user agent has to support a particular extension to render the indicated element.
So, if you have an SVG <foreignObject> element (used to embed non-SVG elements in SVG) with requiredExtensions="http://www.w3.org/1998/Math/MathML" set on it, and then put that <foreignObject> inside a <switch> element, the <math> element will be rendered if MathML is supported, and the next element will be if MathML isn't.
So, for a basic MathML example: <math xmlns="http://www.w3.org/1998/Math/MathML"><mn>1</mn><mo>+</mo><mn>1</mn><mo>=</mo><mn>2</mn></math> is MathML for 1 + 1 = 2.
A basic SVG fallback for this would be <svg xmlns="http://www.w3.org/2000/svg" width="65" height="23"><text y="15" font-size="16">1 + 1 = 2</text></svg> (more complicated fallbacks could be generated with Mathjax-Node).
So the completed MathML expression with fallback would be:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="40">
<switch>
<foreignObject requiredExtensions="http://www.w3.org/1998/Math/MathML" width="120" height="40">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mn>1</mn><mo>+</mo><mn>1</mn><mo>=</mo><mn>2</mn><mtext>MathML</mtext>
</math>
</foreignObject>
<text y="15" font-size="16">1 + 1 = 2 (SVG)</text>
</switch>
</svg>
I have tested the above in Firefox (renders MathML), Edge, IE11 and Chrome (renders SVG). I have not tested Safari, as I don't own a Mac.
EDIT: Safari 9 renders the MathML.
But I want to support IE8!
Why?
BECAUSE!
Fine.
If you want to keep the ability to copy + past your math, you can't use an <picture> tag to embed your SVG/MathML hybrid - use <object> instead:
(I'm using a DataUrl here, but you could just as easily save the SVG as an external file):
<object typemustmatch type="image/svg+xml" data="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjQwIj4NCiAgPHN3aXRjaD4NCiAgICA8Zm9yZWlnbk9iamVjdCByZXF1aXJlZEV4dGVuc2lvbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwiIHdpZHRoPSIxMjAiIGhlaWdodD0iNDAiPg0KICAgICAgPG1hdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwiPg0KICAgICAgICA8bW4+MTwvbW4+PG1vPis8L21vPjxtbj4xPC9tbj48bW8+PTwvbW8+PG1uPjI8L21uPjxtdGV4dD5NYXRoTUw8L210ZXh0Pg0KICAgICAgPC9tYXRoPg0KICAgIDwvZm9yZWlnbk9iamVjdD4NCiAgICA8dGV4dCB5PSIxNSIgZm9udC1zaXplPSIxNiI+MSArIDEgPSAyIChTVkcpPC90ZXh0Pg0KICA8L3N3aXRjaD4NCjwvc3ZnPg==">
1 + 1 = 2 (You don't support SVG)
</object>
(You could render the SVG as a PNG using CloudConvert or similar and put in inside the object if you really wanted.)
So there you go. A little pre-rendering, and you have a MathML fallback that requires no JavaScript or CSS - just HTML.
EDIT: I have made an NPM package to automate the creation of the MathML, SVG, and PNG. It can be found here.
I was not aware of this at the time of my first answer, but you can in fact use the <object> tag to display MathML directly - the MIME type of MathML is application/mathml+xml.
So you can have one <object> tag that points to a mml file, with whatever fallback content you want inside of it (I'd suggest a SVG representation of your equation, possibly in its own <object> for a PNG fallback).
I have tested and confirmed this works in Firefox (MathML is displayed), Edge, Internet Explorer 11 and Chrome (SVG is displayed).
EDIT: Safari shows the SVG, not the MathML. (Even through it supports MathML.)

Firefox issues when displaying SVG (Firefox 55.0.3)

Firefox won't display the SVG book covers properly ...
http://new.images.hindawi.org/kalimat/covers/svg/270x360/c/24972860.svg
Compare the link above in Firefox and Chrome.
It used to be displayed just fine in Firefox, but I think something went wrong with the latest update.
If any one know a solution to this issue it would be great.
Thanks.
If you check your browser inspector, than you will see an error:
There is an SVG reference chain which is too long in this
document, which will prevent the document rendering correctly.
Inside your SVG image there are many of them, looking like:
<path clip-path="url(#SVGID_68_)" fill="#FFFFFF" d="..." />
Either create less accurate SVG (less details), or create it some other way.
Since it is rendered well in webkit browsers, than maybe you can use wkhtmltoimage to convert it server side to PNG or JPG.

How do I see why my SVG isn't rendering?

With Chrome as my target browser, I'm adding a hand-edited SVG image to a webpage. The SVG image doesn't render, and Chrome shows a "broken image" icon in its place.
I suspect that the problem is that my hand-edited SVG has a typo somewhere in it, but without any further information, I'm not sure how to look for the mistake. Some kind of error message would be extremely useful. How do I see the error that prevented Chrome from rendering the SVG?
Have you tried the https://validator.nu/ validator?
Use "File Upload" or "Text Field" and select the SVG preset:
Add name space to your svg tag. Like mentioned below. That should make it work.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>

inline SVG fallback - browsers processing all switch elements

I have just started using inline SVG to display images on a resource heavy website. However, I also have a fallback using switch and foreignobject tags so that older browsers should just display a png image in its place.
Here is the bare bones - there are more details at inline svg in html - how to degrade gracefully?
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xml:space='preserve'
width="100" height="100">
<switch>
<g>
<!-- the svg goes here -->
</g>
<foreignObject width="100" height="100">
<img src="/some_image.png"/>
</foreignObject>
</switch>
</svg>
I thought that this would lighten the load on the server - e.g. for a page with 4 images, the browser gets everything in one hit, rather than making 5 trips to the server, 1 for the page and 1 for each img tag.
However, now that I have deployed this solution, I have discovered (by examining the server logs) that browsers are actually processing the img requests inside the foreignobject tag, regardless of whether they can handle SVG.
In other words, it's increasing the load on the server since the page is much bigger (full of SVG) and the images are downloaded anyway, even though they are never displayed.
This seems crazy - I thought the idea of a switch was that the browser should process the first tag it understands (in my example, the g tag) and ignore the rest (the foreignobject in my example).
I have tested this in Firefox 17.0.1, Chrome 23.0.1271.95, Safari 5.1.7 and Opera 12.10 and they all do it.
Is there any way I can persuade the browsers that they really really don't need to download the images?
Thanks
Chris
You can still make reference to the content of a <switch> child that isn't directly displayed by using it in a <use> <filter> or <clipPath>. It's only direct rendering of switch children that is suppressed.
The only way to stop downloading would be not to set the src attribute on the image unless you need it. You could check for SVG support using javascript e.g.
document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Shape", "1.0")
and then set the src attributes if that returns true.

How to load a HTML file into canvas?

I know we can load an image into a canvas but I wonder if we are able to load a simple HTML file into a canvas. If yes, how?
Thanks.
Short answer: No, you cannot.
Long answer:
Not reliably, BUT yes you can in certain (possibly hackish) ways. The key is in what you define as an "image". You are aware that you can add an image to the canvas with drawImage() - what you mightn't be aware of is what that "image" can be (not necessarily an actual image).
Firstly, the "image" can be a HTML5 video element - so you can add videos to the canvas.
Secondly, in most modern browsers the "image" can be an SVG document, which can contain HTML via the SVG <foreignObject> element.
Browser support:
SVG documents in drawImage() are not currently supported in Firefox. The related bug is here and I think a fix is planned.
<foreignObject> is buggy in most browsers - Firefox (ironically) seems to have the best support.
Example:
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject x="0" y="0" height="800" width="800">
<body xmlns="http://www.w3.org/1999/xhtml">
<p>Hello world!</p>
<input type="date"/>
</body>
</foreignObject>
</svg>
Try loading that file with canvas drawImage() in Opera - as you'll see its interactivity is fairly buggy, but it displays fine.
He's talking about HTML5 / Javascript.
It's not possible without writing your own Rendering Engine (in Javascript).
html2canvas or rasterizeHTML.js seem the tools you are looking for.
A third solution without plugins is presented by Mozilla, but I could not get it running here: Although it's not trivial (for security reasons), it's possible to draw DOM content—such as HTML—into a canvas.
There is also PhantomJS, which supports Screen Capturing