Render RGBA to PNG in pure JavaScript? - javascript

Let's say I have a canvas element, and I need to turn the image on the canvas into a PNG or JPEG. Of course, I can simply use canvas.toDataURL, but the problem is that I need to do this a twenty times a second, and canvas.toDataURL is extremely slow -- so slow that the capturing process misses frames because the browser is busy converting to PNG.
My idea is to call context.getImageData(...), which evidently is much faster, and send the returned CanvasPixelArray to a Web Worker, which will then process the raw image data into a PNG or JPEG. The problem is that I can't access the native canvas.toDataURL from within the Web Worker, so instead, I'll need to resort to pure JavaScript. I tried searching for libraries intended for Node.js, but those are written in C++. Are there any libraries in pure JavaScript that will render raw image data into a PNG or JPEG?

There have been several JavaScript ports of libpng, including pnglets (very old), data:demo, and PNGlib.
The PNG spec itself is pretty straightforward – the most difficult part you may have is with implementing a simple PNG encoder yourself is getting ZLIB right (for which there are also many independent JavaScript implementations out there).

There's actually a C++ to JavaScript compiler called Emscripten.
Someone made a port of libpng, which you might want to check.

I was able to write my own PNG encoder, which supports both RGB and palette depending on how many colors there are. It's intended to be run as a Web Worker. I've open-sourced it as usain-png.

Related

How to display a QPixmap in QWebEngine?

I'm trying to figure out what is the best and most efficient way to display a QPixmap or a QImage in a QWebEngine frame.
My goal is to display a video that is being loaded from a custom network camera, which we have a C++ API, in the QWebEngine frame, with maximum efficiency. So saving the frames to the disk and then loading them on the QWebEngine frame, is not an option.
Previously, I was using Qt WebKit and it was pretty straight forward to load a QPixmap created in C++, because it was accessible through a Javascript object. But now, I'm interested in QWebEngine due to multiple purposes.
However, in QWebEngine, it seems that there is no way to directly attach QObjects to the frame window object.
So my question is what is the most efficient way to transfer a image, or a byte array, to be shown in QWebEngine?
One of the fastest ways to draw QPixmap is QGraphicsScene::addPixmap. And it is very comfortable way. Or just draw it on QLabel.
Drawing pixmap with QWebEngine and JS is really bad idea. It is slow and WebEngine is big Chromium browser under the hood, so it is + about ~60 mb libraries.
My goal is to display a video that is being loaded from a custom
network camera, which we have a C++ API
If you need only this as you said, you don't need QWebEngine, only your network method to obtain image and QGraphicsScene to draw. It is really fast and good for video.
But if you want it so much you can, for example, paste image with JS through clipboard :)

Decode JPEG in web worker

How can I decode a JPEG in a web worker to get access to the pixel data, without including code (written by myself or 3rd party) to decode the JPEG, but using a built-in browser API.
I understand that I can render a JPEG to a canvas in the main thread, read off the pixel data, and pass it to the worker if that's where I want it, but I am specifically investigating the possibilities of decoding the JPEG in the worker.
I also understand that I can use a third party library, but I am wondering if there is anything built into browsers that can do this, since it seems strange to have to send code that duplicates browser ability.
tl;dr: No.
After your edit, the question whether you can use built-in API (which is only canvas at this moment) the answer is no. You cannot create HTMLElements, including canvas in web workers because they are GUI components and most GUI frameworks refuse to allow GUI component instantiation outside GUI thread.
This is of course quite unfortunate, it means there's no way to use native API (CanvasRenderingContext2D) to do any image operations at all.
Your question as I answer it now was already asked and answered: Web Workers and Canvas
I would suggest favoriting that question for updates - I hope as well that in future image processing will be possible in web workers.

nodejs make image from smaller images?

I have some small images that tiled together make a fullsize image. The tiles are saved on the server. I would like to stitch the tiles together in the right position and create 1 image file on disk made up of all the tile files. How can I do this in nodejs?
Thanks
Your best bet is probably to invoke a tool like ImageMagick, which has a montage command that does exactly what you're looking for.
This would be fairly straightforward to implement yourself, but I see that this fork of node-imagemagick has montage support.
Since node.js doesn't have a graphics editing suite, your best path would be to
You could call an external script, using java, using php, or the language you feel most comfortable hacking with.
There's plenty of material on how to run a script from node.js, so I won't mess around with that here.
However, I would suggest that you pass a temporary filename as an argument to the script, then when it finishes executing, go get that file rather than trying to read back the binary as a return value or something equally convoluted.

Javascript lossless image compression

I am looking for a way to encoding a bmp image as a tiff or some other standard, compressed but lossless format in a browser (javascript). I guess if worst comes to worst I can write a library myself (getting the data from a canvas element) but I was hoping either: there's a better way to do it or someone else has already written something similar (I can't find a library).
I have users wanting to upload ~ 4mb (8-bit monochrome) bmp files, which I can losslessly compress to ~700kb tiff files with LZW (or even better ~300kb lossless JPEG-2000). I'd like to do this before the files are uploaded to save transfer costs/time.
Before you ask, I'm not being anal about the lossless encoding instead of just using high bitrate JPEG. These are astronomy photos that are used for analysis so they can't handle any compression artifacts being introduced.
Thanks,
Jonny
Use PNG. It's lossless and uses zlib compression. There are even programs like pngcrush that will optimize the image for size (only problem is it takes a while for this).
Is there any reason you're using JavaScript of all things for this process? Wouldn't it be easier in the long run if you did it in a Java applet (using a library that interfaces with the java.awt.Image class), or uploaded it to a server that did the image processing and returned the compressed image?
Edit: Please don't use a Java applet; the technology isn't well-supported anymore.
If you are willing to experiment something new, you could try a new lossless compression algorithm I created; through a Java applet it is possible to visualize the compressed images in a browser. You could use Javascript to trigger the loading of the applet, or manipulate directly the Java code (the program is open source). For many images, the compression ratio will be better than lossless Jpeg 2000. The address of the website is http://www.researchandtechnology.net/bcif/ .
If instead you want to use some well-known standard, then I'd agree with amphetamachine: using PNG would be the best choice.
So long,
Stefano

Is it possible to optimize/shrink images before uploading?

I am working on a web application that will deal with many image uploads. Its quite likely that the users will be in areas with slow internet connections and I'm hoping to save them upload time by compressing the images before uploading.
I have seen that Aurigma Image Uploader achieves this using a java applet or active x but it's expensive and I'd rather something open source or at least a little cheaper. Ideally I'd like to roll my own if its at all possible.
I'm developing on Ruby on Rails if that makes any difference..
Thanks!
Edit just to clarify: I don't mind if the solution uses activeX or an applet (although js is ideal) - I'm just looking for something a little cheaper than Aurigma at this stage of development.
Also, it may not be feasible for users to shrink the image themselves as in many instances they will uploading directly from an internet cafe or other public internet spot.
Generally, it isn't possible to write an image compressor in JavaScript. Sorry.
You'll need to use a plugin of some sort, and as you mention, other sites use Java.
It appears to be possible to write something to encode a JPEG in ActionScript (i.e. Flash), which will reach a much larger audience than the Java plugin you mention. Here's a link to a blog post talking about PNG & JPEG encoders in ActionScript.
Here's another blog post with a demo of an inlined JPEG encoder in ActionScript.
Only if you use Flash or Silverlight (only way to be cross-platform)
http://www.jeff.wilcox.name/2008/07/fjcore-source/ may be worth a read.
Without using applets or activex (only in windows) you can't execute anything on a client pc.
Probably not, but you can always insist that image uploads over x size will not succeed.
Is this an application where you can force them to insert a smaller image. In that case you could grab the size first to verify it fits standards. This is what facebook used to do with profile pictures. If it was too big they wouldn't take it.

Categories