5

Is there any way to use a Canvas Element inside of a Web Worker? I want to do canvas.toBlob inside of a Web Worker to reduce the quality of an image.

  • I know only ImageData can be passed to the Web Worker, that doesn't help me, I need the canvas, not the canvasContext to do canvas.toBlob
  • I know about the experimental offscreen Canvas in Firefox, I want support in other browsers aswell though.

Like maybe somehow through https://github.com/substack/webworkify webworkify? Which allows to require other libraries inside a web worker?

I either need to pass a canvas elment to a Web Worker, or create a canvas Element inside of the Web Worker, or find an alternative way to reduce the quality of an image.

bergben
  • 1,385
  • 1
  • 16
  • 35
  • try OffscreenCanvas https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas – defghi1977 Dec 09 '16 at 01:09
  • 1
    thanks but please note the second point listed with a dot in front in my question – bergben Dec 09 '16 at 01:34
  • Currently no cross browser way yet to get web worker maniplulate DOM – Vinay Dec 09 '16 at 02:04
  • If you want rendering done on a worker so that it is not blocking your main page there are various implementations of the Canvas2D API written in javascript. but none use the GPU so performance will be very low. But you say you want to reduce the quality??? So its not the canvas API you need but a Image encoder (jpg, png, webp, bmp??) There are plenty of javascript image encoders that you can just pass the pixel data to – Blindman67 Dec 09 '16 at 02:55
  • yes other ways to reduce the image quality would be fine as well, if you know any @Blindman67 I don't even want to manipulate the DOM, I just want to reduce an image file's quality before uploading it... but so far I only know one way to do that which is through a Canvas and then .toBlob where you can set the quality as third parameter – bergben Dec 09 '16 at 10:24
  • 1
    You can also use `canvas.toDataURL("image/jpeg",quality)` Why do you want to do it on a worker, it would probably take longer to start up a new context for the worker, parse the javascript, pass on the pixel data, then a very slow javascript implementation of jpeg encoding, and so on. By the time the encoded data returns you could have done it a dozen times using the native calls. – Blindman67 Dec 09 '16 at 12:27
  • 1
    With canvas.toDataURL I would still need the canvas. I want to do it in a web worker because I am calling it recursively to create a function that reduces the quality image just enough to fit a certain file-size limit but not further than needed, for which I created an algorithm that usually finds the best possible quality in 2 to 5 steps... – bergben Dec 09 '16 at 14:17
  • @bergben, Dam Chrome, I need this too for GPGPU. – Pacerier Apr 13 '17 at 04:12
  • @Blindman67, Re "*Why do you want to do it on a worker*".. Dude, yours is a completely dull question really. Because it hangs the UI thread duh? And what very slow implementation are you talking about? The `canvas.toBlob` call is sent directly to the browser. – Pacerier Apr 13 '17 at 04:21
  • Related: http://stackoverflow.com/q/8170431/632951 – Pacerier Apr 13 '17 at 04:22
  • @Pacerier There is no canvas.toBlob available to the workers. duh – Blindman67 Apr 13 '17 at 05:22

1 Answers1

5

Use OffscreenCanvas:

OffscreenCanvas objects are used to create rendering contexts, much like an HTMLCanvasElement, but with no connection to the DOM. This makes it possible to use canvas rendering contexts in workers.

An OffscreenCanvas object may hold a weak reference to a placeholder canvas element, which is typically in the DOM, whose embedded content is provided by the OffscreenCanvas object. The bitmap of the OffscreenCanvas object is pushed to the placeholder canvas element by calling the commit() method of the OffscreenCanvas object's rendering context. All rendering context types that can be created by an OffscreenCanvas object must implement a commit() method. The exact behavior of the commit method (e.g. whether it copies or transfers bitmaps) may vary, as defined by the rendering contexts' respective specifications. Only the 2D context for offscreen canvases is defined in this specification.

This is an experimental feature, so it is hidden behind a flag. It is supported by Firefox:

This feature is behind a feature preference setting. In about:config, set gfx.offscreencanvas.enabled to true.

And Chrome:

This feature is behind a flag. In chrome://flags click enable under Experimental canvas features

For the worker use cases, there is no dependency on the DOM:

Web workers are not DOM-dependent. They handle pure data, which makes them especially suitable for JavaScript code that takes a long time to execute.

Only Firefox supports the ImageData manipulation.

Canvas Web Worker Support

References

Community
  • 1
  • 1
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265