Gradual Rendering of Progressive Images in HTML5 Canvas - javascript

Is there a way to draw partially loaded progressive Image objects (PNG, JPG) into canvas?
Most browsers support progressive loading in the tag, but I can't find how it can be controlled in within canvas.

The answer is no, as per the specification's orders.
If a browser does happen to do this, it is against the spec, which states:
If the image isn't yet fully decoded, then nothing is drawn.
When an img element is in the completely available state and the user agent can decode the media data without errors, then the img element is said to be fully decodable.

You can take a look at streamingtextures js lib
which use custom decoding of progressive JPEG images (via Emscripten version of libjpeg) and return image content as an array of bytes.
This method is used with WebGL but could be also used for 2D canvas and extended to support also GIF, PNG and WebP

Related

Is it possible to resize an image that is stored in a Uint8Array without using the browser's built-in canvas implementation?

I need to compress and rotate the image in the browser. Image sources can be drag'n'drop from a local user or the image can be downloaded from an URL with the same domain as the page with this script. But asking for permission to use HTML5 canvas doesn't fit into the design specification in any way.
The image can be in JPEG, PNG or HEIC format and in the current implementation is stored in Uint8Array. Is it possible to generate a thumbnail or change image orientation without using canvas?
No browser that I know of will ask for permission to use a canvas. Using a canvas is the quickest solution to do this (it's very simple indeed), and HEIC support is easy too: https://alexcorvi.github.io/heic2any/

OpenGL or other image processing in the browser, without canvas?

I'm trying to find a way to make a program similar to after effects or blender in the browser, in the sense of developing certain animations etc., and compiling the animations and keyframes info a video, preferably frame-by-frame
Using the built in methods of the canvas and media recorder, I have yet to find a way to process a video by inserting one frame at a time, to a set framerate, usually the media recorder just records live in real time, it doesn't seem to be meant for frame by frame rendering, and also the canvas is limited in the sense of being too slow or unreliable to consistently get the image from it using either toDataURL or glGetPixels etc.
Is there a way to process videos in JavaScript without using the canvas at all?
Meaning, instead it would just generate the image data and display it as an img tag, or even a real time low quality video encoding and streaming, on the client side, and attach the stream to a video tag somehow, or perhaps the canvas could be used for development of the keyframes etc. but the actual processing would be done by scratch, is this the best way to go about this? And if so, how can it be done?

How to compress .png images when exporting from Canvas using toDataURL()?

Need to generate .png images that are about ~20k in size using HTML5 canvas. Unfortunately, when creating .pngs using the toDataURL() method, you cannot specify quality like you can with jpegs.
Any ideas for a workaround? toDataURL seems to be the only way to generate images from Canvas and canvas seems to be the best tool for image processing without server interaction. Appreciate any suggestions.
There IS a way to have compression for PNG images using lossless zlib deflate process http://www.w3.org/TR/PNG-Compression.html . There is a library (https://github.com/ShyykoSerhiy/canvas-png-compression) that provides shim for HTMLCanvasElement.toDataURL() when image type is 'image/png' and enables ability to provide 'quality' as second parameter to HTMLCanvasElement.toDataURL() for png.
NOTE that it provides better results(smaller size) only in Chrome. Firefox sometimes has better compression than canvas-png-compression(as for 0.0.3 version).
You can do something by scaling it down and then scaling it up again.
Scale down by drawing it on a smaller canvas, then get the data url.
Create an image object set the data url as its source.
Draw on the original canvas with this img object (obviously inside the onload event callback)
Find the size ratio of the canvases to give you optimum result by experimenting a bit.

Access raw YUV values from JPEG with JavaScript

I have dynamically loaded a JPEG image into a 2D html canvas and I would like to access the raw YCbCr pixel values.
From what I understand, JPEG encodes the pixel data in YCbCr, but chrome appears convert it to RGB when accessing it with getImageData().
I have tried using the RGB to YCbCr conversion calculations but it appears to be a lossy conversion as they don't map perfectly 1-to-1.
Is it possible to access the raw YCbCr pixel values in JavaScript?
Yes and no.
When the browser loads an image with the native methods (ie. Image element) the YCbCr (in case of JPEGs) are automatically converted to RGB space by the browser and ICC and gamma correction is applied by browsers which support that.
This mean that when the image is loaded and ready for use, it is already in RGB space (which is correct as the monitor is RGB). The canvas does not have a part in this process and will always contain pixels as RGBA. All browsers supporting canvas will therefor return the data as RGBA when using getImageData().
The only way to access raw YCbCr is to do a low-level parse of the raw file yourselves. You can do this in any language that can iterate bytes including JavaScript. For JS I would recommend using typed arrays and DataViews to parse over the data but be warned: this is tedious and prone to errors (as it is a whole project on its own) but fully possible to do if you absolutely need the raw data.
Another way is to convert RGB back to YCbCr but chroma and the aforementioned color- and gamma-corrections will probably affect the result not making it identical to the original raw data (which in any ways is in compressed form). You can also export canvas as JPEG using the toDataURL() method on the canvas element.
I know this is a very old question, but wanted to provide the update that Chrome now rasterizes some JPEG and WebP images directly from YUV planes. You must have GPU rasterization enabled (and Metal disabled) and might sometimes need to enable the feature from chrome://flags
You can run a trace, decode an image, and include the blink category and see if any events pop up for YUV decoding. If so, then you can experiment with trying to directly access the YUV planes from JavaScript, although I'm admittedly doubtful that will work out of the box (for plumbing/security reasons).

Convert Image element with CSS3 filters to a Blob

Assuming the following HTML structure:
<div id="image-blob" class="filter-wrapper">
<img id="pic" src="">
</div>
I'm applying CSS3 filters such as -webkit-filter: blur(1px) brightness(1.5) contrast(1.8) drop-shadow(black 16px 16px 20px) grayscale(0.2) hue-rotate(90deg) invert(0.1) saturate(3.6) sepia(0.3); to the <img> element.
Is it possible to convert this rendered image with the filters into a blob which is to be downloaded by the end-user without involving any server side process / proxy?
Note: Client-side download is being done using FileSaver.js and possible conversion to canvas using HTML2Canvas
Edit:
Further investigation shows that this might not be possible (proving this wrong is most welcomed) and the only solution might be to replicate these filters via javascript in the canvas itself. Pixel Manipulation Tutorial or a solid library such as CamanJS.
#NielsKeurentjes correctly points out that browsers prevent javascript from saving of most web page content locally for security concerns.
However, I offer that you could use canvas to do your image filters.
Then simply convert the canvas to an image and open the modified image by itself in a new browser tab.
Instruct the user to "right-click-save-as" and you're good.
I suggest this method for a couple of reasons:
Users are often aware of (and comfortable with) the right-click-save-as method.
Even if you find a hack to force JS save locally, browsers will consider the hack a security concern and eventually forbid the hack. Not to mention, hacks are almost always cross-browser nightmares.
BTW:
In addition to CamanJS, Pixastic is another good image filter library:
http://www.pixastic.com/lib/docs/

Categories