Project: chromium Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Issue 67587 Add toBlob to Canvas element.
Starred by 186 users Reported by downch...@gmail.com, Dec 20 2010 Back to list

Comments by non-members will not trigger notification emails to users who starred this issue.
Status: Fixed
Owner:
Last visit 28 days ago
Closed: Feb 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Launch-OWP
Launch-Accessibility: ----
Launch-Legal: ----
Launch-M-Approved: ----
Launch-M-Target: ----
Launch-Privacy: ----
Launch-Security: ----
Launch-Status: ----
Launch-Test: ----
Launch-UI: ----

Blocked on:
issue 523414
issue 567887
issue 568603

Blocking:
issue 523417



Sign in to add a comment
Currently, the html5 canvas element has a toDataURL method, which outputs a DOM string representing the backing bitmap. With the File API now widely implemented, it is appropriate to add a similar getBlob method, one which would return a Blob object. Passing Blob pointers around is quite a bit more efficient than passing large base64 encoded strings.
 
This issue is already being discussed on whatwg
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-December/029492.html



Comment 2 by downch...@gmail.com, Dec 21 2010
I didn't understand the poster's need for a toFile method. I'll reply to that post and get discussion moving along; I don't expect any resistance from Mozilla. I don't think IE will have much in the way of Blob support in IE9.
Comment 3 Deleted
The toFile() idea came from Mozilla :)  The whatwg community discussed if a blob-based method might be better, that was ~11 months ago.  You mentioned blob pointers in this report and there is something like that on the platform now: window.createObjectURL().
Comment 5 by downch...@gmail.com, Dec 27 2010
Yes: currently we're decoding toDataURL strings into Blob pointers, then using createObjectURL. I'll try to bring it up with the whatwg. It seems straightforward now: Blob semantics were not as well defined in last January.

There are some nasty issues with large data uri strings in WebKit; issue #25047 attempts at a demonstration.

Here's a webkit tracker for adding getBlob:
https://bugs.webkit.org/show_bug.cgi?id=51652


Comment 6 by noel@chromium.org, Jul 12 2011
An async API, canvas.toBlob(), has been speced for HTML5
 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-toblob
 http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-April/031243.html
Comment 7 by noel@chromium.org, Aug 15 2011
Issue 83103 has been merged into this issue.
Labels: -Area-Undefined Area-WebKit
Owner: noel@chromium.org
Status: Assigned
Checking in -- Possible target for M release?
Slightly related, issue #32498, capturing screen shots from chrome extensions. 
Noel, any updates on this?
Cc: kinuko@chromium.org
Issue 123095 has been merged into this issue.
+1 on this feature, it would make video streaming more viable. currently the only method of taking a getUserMedia stream and getting image frame data from it is to stream it into a <video> tag and then render that <video> as fast as possible into a <canvas>. using toDataURL on the canvas takes about 100ms using webp and the lowest possible quality, but this is about 3x too slow for realtime streaming use cases (33ms is 30fps).

if getBlob is <= 33ms then that would be awesome!
Labels: not-webrtc
FF landed this https://bugzilla.mozilla.org/show_bug.cgi?id=648610
This is a prereq for us supporting larger size output on http://developer.android.com/distribute/promote/device-art.html
Comment 18 by aren...@gmail.com, Dec 18 2012
Another +1 for this feature. I'm creating an HTML5 mapping application, and support exporting maps to PNG. While this works with the use of data URLs, it is very inefficient, and simply chokes when the maps become too large. I hope the latter problem will be at least reduced when using blobs.
It looks like Noel has already started this in WebKit; see https://bugs.webkit.org/show_bug.cgi?id=71270
Looks like the WebKit bug report has been abandoned; a WebKit dev asked if it was ready for review about six months ago, the patch has not been updated in over a year.
Are there any plans of implementing it soon?
wkb.ug/71270
wkb.ug/51652
Project Member Comment 22 by bugdroid1@chromium.org, Mar 10 2013
Labels: -Area-WebKit Cr-Content
Project Member Comment 23 by bugdroid1@chromium.org, Apr 6 2013
Labels: -Cr-Content Cr-Blink
Hey guys.  This has been "assigned".  I'm assuming someone is working on it, or it's at least on their task list.  Can we get an update?
+1 for this. Current option of canvas.toDataURL -> new Blob() is a wasteful operation. Any hope adding this to Blink?

Labels: Cr-Blink-Canvas
Duplicate of Issue 229053 ?
Yes, it's a duplicate but the status on that patch is not well defined... It simply shows as "RESOLVED-WONTFIX"

https://bugs.webkit.org/show_bug.cgi?id=71270
Comment 29 by junov@chromium.org, Jul 25 2013
Cc: junov@chromium.org
Summary: Add toBlob to Canvas element. (was: Add getBlob to Canvas element.)
It would be great to have toBlob, since it's more natural for apis to accept BLOBS instead of www encoded requests.
In the mean time, there is this project https://github.com/eligrey/canvas-toBlob.js
Support for this would be great !
Mozilla also got it working off the main thread: https://bugzilla.mozilla.org/show_bug.cgi?id=817700
+1 for this feature. We will need it in Chrome OS for Files app to save files to disk, as well as in the Camera app for the same. Currently, we have to decode the base64 from toDataURL, which is expensive and tricky.
Comment 35 Deleted
I found toBlob was the only way I could record more than 30 seconds of webcam video for playback within the browser.  This only works on Firefox, so I'm hoping Chrome will implement toBlob.

In my scenario, I'm capturing frames of video from the webcam for delayed playback to the user.  Everything I tried with Chrome would crash the browser when I tried to record more than 20s or 30s of content.  I tried storing each frame in a canvas, keeping the getImageData() result, things like that.  Using toBlob() on Firefox was the only solution to work.
To comment #36,

Thanks, useful feedback.
What would be the best cross browser solution for less than 30 seconds recording?
I don't know how cross-browser this is, but on both Chrome and Firefox I could store each video frame in a canvas, so as the webcam video is running I would capture a frame with:

    function createCanvasCloneOf(videoElement) {

        var canvas = document.createElement("canvas");
        canvas.width = videoElement.videoWidth;
        canvas.height = videoElement.videoHeight;

        var context = canvas.getContext('2d');

        context.drawImage(videoElement, 0, 0);

        return canvas;
    }

You might be able to use canvas.toDataURL on more browsers.  I don't recall if I did precise measurements but my recollection is that using toDataURL was slower than writing to/from canvas elements.

#38 - what you're doing is storing a blitted bitmap on each frame. This has heavy costs in RAM but almost no cost in CPU usage.

toBlob takes that bitmap and compresses it into a png or jpg frame, relying heavily on the CPU but reducing the RAM needed considerably, provided the CPU can keep up.

toDataURL does the same thing as toBlob, but it re-reads the resulting data and expands it about 30% in size, converting it into a string. It's a completely unnecessary step but all that was available in the earlier canvas apis.

What #36 is looking for is more like the record functions that were proposed; these would actually record a canvas into something like a webm file, getting far better compression than a series of frames would handle. Such a request is a bit different than the main request here.

Here we're just looking to get rid of the unnecessary overhead of taking binary PNG data and converting it into a larger base64 encoded string, then decoding it later.
@#39: Blobs have another very important aspect that should not be neglected: they are not constrained by RAM.  A blob's data can be fully or partially swapped to disk. So the number of frames that can be stored in blobs can be several orders of magnitude higher that what can be achieved with toDataURL, which produces a string, which is necessarily stored in RAM, on the JavasScript heap.
Comment 41 by vli@chromium.org, Nov 19 2013
Labels: Hotlist-DevRel
Comment 42 by fschw...@gmail.com, Nov 19 2013
Just an update, I put together a capacity test that would accumulate video frames on the client to see how far it will run before the browser crashes.  That capacity test is here: http://internetdancefloor.com/captest

When you run it, you can pick a collection method (the implementation of each are here: http://internetdancefloor.com/client/capacityTest/capacityTest.module.js).  It then records frames within the browser until the browser crashes, periodically writing its progress to local storage.

So to run the test, pick a test method, click start, enable your webcam, and let the browser run until it stops working.

In some cases it can take ten minutes or so to crash, but what I found is that I get pretty good results with canvas.toDataURL("image/jpeg"), which now works on Chrome and Firefox.  Firefox does seem to handle running out of memory better, but that could be a problem in my code.  So I am no longer using toBlob.

All of this is cobbled together code, so my results are hardly conclusive.  Actually now I'd like to be able to copy a video or canvas image directly into an IndexedDB record.  This way there is no memory pressure, and I can carry on if the browser is restarted.
Comment 43 Deleted
Until this interface is actually implemented like it should, "new Blob(CanvasRenderingContext2D.getImageData(...));" should be a pretty good workaround for now, I would imagine...
Comment 45 Deleted
I think there's one step missing: you've got to pass the Uint8ClampedArray to the Blob constructor, not the whole ImageData structure:

"new Blob(CanvasRenderingContext2D.getImageData(/* args here, or not */).data)"
Comment 47 by d...@mixbook.com, Dec 31 2013
I'm unable to convert ImageData.data to a Blob in Chrome 31. The code:

"new Blob(CanvasRenderingContext2D.getImageData(/* args here, or not
*/).data)"

results in the following error:

TypeError: First argument of the constructor is not of type Array.
Working version:

var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");

var rawPixelBlob = new Blob([ctx.getImageData(0, 0, canvas.width, canvas.height).data]);

`rawPixelBlob` ends up containing raw pixel data and hence has two problems:

1. it will be generally larger than a PNG or JPEG
2. probably cannot be used as an image with URL.createObjectURL.
The low-performance workaround that gives you an actual formatted image in your blob:

//take apart data URL
var parts = canvas.toDataURL().match(/data:([^;]*)(;base64)?,([0-9A-Za-z+/]+)/);

//assume base64 encoding
var binStr = atob(parts[3]);

//convert to binary in ArrayBuffer
var buf = new ArrayBuffer(binStr.length);
var view = new Uint8Array(buf);
for(var i = 0; i < view.length; i++)
  view[i] = binStr.charCodeAt(i);

var blob = new Blob([view], {'type': parts[1]});

//And then if you want to do something with that blob...
var URL = URL.createObjectURL(blob)

(taken from https://code.google.com/p/chromium/issues/detail?id=69227#c37)
Comment 50 Deleted
Our personal problem is how to get scaled/cropped/resized JPEG/PNG/BMP from canvas RGBA.
We use Benjamin approach to do similar things, but we should process alot of images, so we dreamed about similar functionality implemented to work in WebWorkers.

Still we have to use own javascript implementation of this, which is low-performance.


Would LOVE to see this working.  toBlob in Firefox is so much faster, and upload is smaller then toDataUrl png format (assuming a photo is in the canvas, and not an svg drawing / other image better suited for png format).
This is still open from 2010! 
Is the people assigned to this ticket still the right one to implement it or maybe it need to be reassigned?

When I try to save 41Mpixel images, Chrome crashes. Currently we have to allocate more memory to run through the intermediate ASCII buffer returned by toDataURL and use the Uint8Array to convert in binary.

This is the only thing that prevent us to make our WebGL picture editor work with images bigger than 20Mpixels. Regarding the rest, it is actually faster than Lightroom.
Comment 54 Deleted
Comment 55 Deleted
The performance of the toBlob shim can be increased by about 30% with loop unrolling bitshifting.

function toBlob( callback, type, quality )
{
	const bin = atob( this.toDataURL( type, quality ).split(',')[1] ),
	len = bin.length,
	len32 = len >> 2,
	a8 = new Uint8Array( len ),
	a32 = new Uint32Array( a8.buffer, 0, len32 );

	for( var i=0, j=0; i < len32; i++ )
	{
		a32[i] = bin.charCodeAt(j++) |
			bin.charCodeAt(j++) << 8 |
			bin.charCodeAt(j++) << 16 |
			bin.charCodeAt(j++) << 24;
	}

	let tailLength = len & 3;

	while( tailLength-- )
	{
		a8[ j ] = bin.charCodeAt(j++);
	}

	callback( new Blob( [a8], {'type': type || 'image/png'} ) );
}
The performance of the toBlob shim can be increased by about 30% with loop unrolling and bitshifting.

if( !HTMLCanvasElement.prototype.toBlob )
{
	Object.defineProperty( HTMLCanvasElement.prototype, 'toBlob',
	{ 
		value: function( callback, type, quality )
		{
			const bin = atob( this.toDataURL( type, quality ).split(',')[1] ),
			len = bin.length,
			len32 = len >> 2,
			a8 = new Uint8Array( len ),
			a32 = new Uint32Array( a8.buffer, 0, len32 );

			for( var i=0, j=0; i < len32; i++ )
			{
				a32[i] = bin.charCodeAt(j++) |
					bin.charCodeAt(j++) << 8 |
					bin.charCodeAt(j++) << 16 |
					bin.charCodeAt(j++) << 24;
			}

			let tailLength = len & 3;

			while( tailLength-- )
			{
				a8[ j ] = bin.charCodeAt(j++);
			}

			callback( new Blob( [a8], {'type': type || 'image/png'} ) );
		}
	});
}
Comment 58 by ise...@gmail.com, Nov 26 2014
Is Noel still around? This bug has been assigned to him for 3 years and 3 months, and he hasn't said anything in this issue since being assigned to it.

Can someone please assign this bug to someone else if Noel is no longer active on Chromium?
I reported it as issue:
https://code.google.com/p/chromium/issues/detail?id=436996
Issue 436996 has been merged into this issue.
Here is an alternative workaround based on https://code.google.com/p/chromium/issues/detail?id=308768 (Fixed Oct 22nd 14)
Around 16% slower than decoding the base64 manually, but returns quicker since the decoding is async.
( responseType='blob', throws a security exception for the time being )

HTMLCanvasElement.prototype.toBlob || Object.defineProperty( HTMLCanvasElement.prototype, 'toBlob', { 
	value: function( callback, type, quality ) {
		var xhr = new XMLHttpRequest;
		xhr.open( 'GET', this.toDataURL( type, quality ) );
		xhr.responseType = 'arraybuffer';
		xhr.onload = function(e) {
			callback( new Blob( [this.response], {type: type || 'image/png'} ) );
		}
		xhr.send();
	}
});
The toDataURL method is synchronous and the polyfills (@#61, @#57) still depend on calling toDataURL synchronously as well. Since toBlob has the advantage of being able to run asynchronously, shouldn't this be a priority to avoid janking?
Comment 63 Deleted
Comment 64 by rob@robwu.nl, Mar 17 2015
Issue 229053 has been merged into this issue.
Comment 65 by junov@chromium.org, Mar 19 2015
Status: WontFix
Copy-pasting discussion from blink-dev:

<---snip--->

On Thu, Mar 19, 2015 at 12:13 PM, 'Noel Gordon' via blink-dev <blink-dev@chromium.org> wrote:

https://code.google.com/p/chromium/issues/detail?id=67587 was written to solely inform the toBlob spec. That it was wrong in fact, it did not handle canvas tainting. The spec text was changed to correct for that as a result.

The practical fix for tainting, and to make the api sane, is to snapshot the canvas buffer and send that to another thread for encoding. That'd double memory use at least, the very thing the api was proposed to avoid, and I'm not sure that fits well with Blink's mobile focus.

There is only one spec implementation (Mozilla). What might progress things is some implementation experience. Was it faster than toDataURL, did it use less memory, and so on, as promised? If not, why implement it?

@Justin, should we ice this until better details about real implementation experience appear? The tainting issue is real [1] and implies a snapshot. I think people's expectations about this api are wrong re: memory use.


On Thursday, March 19, 2015 at 5:47:58 PM UTC+1, Justin Novosad wrote:

I think the key point is that we should not implement features that offer no significant advantage over a JS library that implements the same functionality. 

The data we have at this time:
a) Noel's exploratory implementation revealed that there are no real memory footprint savings due to the need for intermediate copies.
b) The cost of encoding synchronously on the main thread (with toDataURL) can be worked around by using getImageData() and encoding in a Worker.

We hear the developer community loud and clear on this issue, but unfortunately there is a wide gap between what many people expect from toBlob, and what is actually possible given various constraint (e.g. data security and thread-safety) that apply to Blink and to the Web platform in general. Right now, many of you are asking for toBlob, but what you really want is a faster, less janky, leaner alternative to toDataURL. Unfortunately, toBlob is not that --or at least not by a significant margin.

That being said, if someone does come up with a brilliant revolutionary idea that would be significantly awesomer than what we have today, we'd gladly consider it.

<---snip--->

With all that, I am closing this issue to make it clear to all who are following that that there is currently no intention to implement this feature.
Currently the only API we have to encode image data to a compressed format is toDataURL, which can encode PNG and JPEG (and in Blink, WebP). So if we have an ImageData, the only way to encode it is to put it back in to a canvas and call toDataURL. In a worker we cannot create a canvas element on which to make this call, since there is no document to call document.createElement("canvas"). The only other option is to compile an image encoder with asm.js, which is a complex project, bloats the JS code, duplicates the browser/OS's own encoder, does not get updated with the browser, cannot take advantage of hardware encoders, and (although this is gradually changing) cannot use advanced CPU instructions like AVX to accelerate encoding. The worker solution also involves double memory use while the ImageData is processed, so it still seems worse than the browser providing a toBlob method.

Temporary double memory use seems a perfectly acceptable - even expected - side effect of an asynchronous toBlob call, and given even phones are now shipping with gigabytes of memory, it seems odd to argue that copying the surface is a problem. A 1920x1080 surface takes a whole eight megabytes of memory. Even a 4K display uses 32mb of memory. Even a Moto E comes with 1 GB RAM. So what about the extra memory use?
Go ahead with a vendor prefixed synchronous method then-- don't throw the baby out with the bathwater.
We get 90% of what we're looking for with minimal effort.

a snapshot is only necessary if the canvas is written to while async is processing. That does imply extra work, so I certainly understand the delay and hesitation in adding an async version.

Note that Microsoft has msToBlob.

Too stupid not to implement this. It's forcing developers to use a polyfill.
Chrome is becoming the new Internet Explorer.
Comment 70 by ise...@gmail.com, Mar 20 2015
Even with the duplication (isn't that temporary?), the memory usage of toBlob is much less than the amount that you get using data URIs.
@70 - the data duplication would be pre-compression, it's sizable. Seems that there is an objection with the spec... But the objection claims that other vendors are completely abandoning toBlob, which I do not think is the case.
Comment 72 by junov@chromium.org, Mar 20 2015
I would like to add that more feedback on use cases would be very helpful here (Help us help you!). In my experience, canvas is often the round hole that everyone wants to fit their square pegs into, just because it is a highly hackable component of the web platform. I think many people rallied behind the canvas toBlob feature because they saw a better solution to something they were already doing using a canvas. But what if there were an even better solution that did not even involve canvases?

Let me give an example: suppose our use case is to transcode a video into a sequence of image files.  Today, one might implement that functionality by using drawImage to draw a video element into a canvas, then call toDataURL on the canvas to encode the frame as a jpeg.  Doing this on a live stream would likely mean a lot of hiccups and dropped frames. Then comes along the toBlob proposal, which sounds like it could make this use case incrementally better, so we rally behind it.  For this use case however, a *real* game changing solution would be one that takes the canvas out of the equation completely, the use of a canvas inherrently implies making an intermediate copy, possibly a round-trip to the GPU, and dividing pixel values by their alpha components upon readback (which is pointless because videos are opaque, but the canvas still has to do it because it supports alpha) etc.

This is just an example, perhaps there already is a better solution to this use case, I did not research it thoroughly.  The point I am trying to make is that for all of you who are disappointed about toBlob not moving forward, it is time to think outside of that box.  The feature did get implemented exploratorily, and it was ascertained the it was too small of an incremental improvement to justify adding a new API.  Every time we add an API, however small it may be, we have to consider that it is something we are going to have to support, maintain and test indefinitely (or for as long as there are websites using it).

To all of you who would have liked to have toBlob, please provide feedback using this form. (Sign-in using your chromium credentials).
Comment 73 by Deleted ...@, Mar 20 2015
Fair enough Junov. My use case is a hightmap and colormap image editor using canvas 2D and then to use the maps to generate terrain in a WebGL game and to export the heightmap to the server for persistence.
To get a URL to a canvas so it can be used anywhere a URL to an image can (such as in CSS properties), the most efficient way is to convert it to a blob and create a URL to the blob. Data URLs have bloat and have to be copied all over the place whereas the browser knows from the same URL it's the same content. If the canvas occasionally changes then you need to keep recreating the blob. toDataURL is synchronous so would keep janking the main thread while it compresses the image every time it changes, whereas toBlob can do that in parallel.
Of course one workaround to that is to allow canvases to be referenced in CSS as images, even if they are not attached to the DOM. Is that part of CSS?
My use case was a browser-based TexturePacker that used canvas to position/visualize the spritemap and then have an API to save canvas to a PNG (alpha transparency definitely required). These spritemaps can get somewhat large. 

Hi,

The decision to "WontFix" something that is in the HTML5 Canvas specification is quite astonishing.


As junov requested, here is a simple use-case on why I would love to have toBlob():

I'm building a web-based video editor to make image slideshow (like this one: http://greweb.me/gl-slideshow-example/ ) and I want to stream frames to the server (e.g; in order to generate a video on that server / stream to youtube / etc..). AFAIK sending blobs seems to be the standard format for the best transport performance (binary instead of string) so it would be an improvement to me.

Also my slideshow is based on WebGL so not using Canvas is not an option to me.

PS: also there might be better solutions for my use-case and Firefox is working on something that looks very promising: https://bugzilla.mozilla.org/show_bug.cgi?id=1032848

Best regards,
gre / @greweb
In my case I'm going to append the result of toBlob() directly to a FormData object. If no toBlob() is provided, I'll have to go to the way described in http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata instead.
Another one: to download a canvas image locally with the anchor "download" attribute, it makes more sense to set the anchor href to a blob URL than to a long data URI.
Comment 80 by junov@chromium.org, Mar 20 2015
Oops, I just realized the link to the form did not "paste". Here it is:

https://docs.google.com/forms/d/1YHIGf2-0wqbeFLA8Y6S-YaFzCWxlw9xPrOn9ctP5JwA/viewform

Please use that to submit feedback
My use case is similar to kxzkxz7's.

- I allow a user to select a profile image (by D&D or upload button)
- then I use a cropper library to let them select the area of the image they want
- the library then uses canvas to crop and resize the image
- I then use toBlob to get a Blob that I can send with XHR2
- Upload progress is then used to display a progress bar as the image is uploaded to the server.
Other Googlers are posting in standards email lists talking about extending toBlob to return a promise and allowing it to be called from a worker via WorkerCanvas. Are you guys all on the same page?
Comment 83 Deleted
Comment 84 by rob@robwu.nl, Mar 21 2015
Regarding #82's comment, here's the link to the discussion: https://lists.w3.org/Archives/Public/public-whatwg-archive/2015Mar/thread.html#msg47
Also this thread: https://lists.w3.org/Archives/Public/public-whatwg-archive/2015Mar/0074.html
Base64/text as a transport for binary is just not acceptable, it was a compromise when it was introduced, it works for things like html and css as they are text based, today we have no excuse with things like blob, typed arrays and buffers to pass large binary around as base64..
I'd like to better understand the buffering concerns here. I'm sure my thinking is naive, but I thought:

context.[drawing command]; // 1
context.[drawing command]; // 2
context.canvas.toBlob().then(callback); // 3
context.[drawing command]; // 4
var data = context.getImageData(…); // 5
context.[drawing command]; // 6
[browser frame]

Lines 1 & 2 would queue up operations to manipulate canvas pixel, but they would not wait on those pixels being painted.

The toBlob call (3)  queues up an operation to create a blob of a PNG of the canvas state. This means the blob would be created once 1 & 2 have applied.

4 queues up another canvas pixel manipulation, explicitly after the creation of the blob.

5 synchronously waits on the operation queue to complete, which includes 1, 2, the creation of the blob in 3, and the operation in 4. Blocking here kinda sucks & feels much like a synchronous layout operation, but hey that's the API we have. Note: callback hasn't been called yet, as promise resolving is a microtask.

6 queues up an operation to manipulate the canvas.

Then we reach the end of the microtask, callback is called with the blob, then we reach the end of the task. The next browser frame is blocked on the completion of 6.

Without the synchronous step 5, the JS wouldn't block on paints (aside from callback).
#87: that's a correct modelling of it - the getImageData is a synchronizing operation (requiring a full flush and sync fetch from the rendering process), where as the toBlob *could* be asynchronous and execute in-order in the render process (whether or not it's implemented like that I don't know).
Hmm, I still don't understand our concerns here then.

In terms of usecases, we want to be able to dynamically create notification images within a ServiceWorker, and we don't want blocking there. https://lists.w3.org/Archives/Public/public-whatwg-archive/2015Mar/0074.html - I now realise the spec is out of date, but you get the idea.
Comment 90 by noel@chromium.org, Mar 23 2015
@jake Hmm, I still don't understand our concerns here then.

toBlob and getImageData would make the same calls under the hood, the sync flush & fetch (readback) to fetch the image buffer. RE: use-cases, and that whatwg message. It's title contains toBlob and Workers: are you running the example given there in a Worker?
Comment 91 by m...@jacobian.se, May 1 2015
My example: An image cropper where the user uploads its image and crops it to her liking. Then when she's happy she clicks "download". Can this even be done without canvas + toBlob? I would love to see an example @junov @noel.
to #91:

Yep, toDataURL works fine.
Comment 93 by m...@jacobian.se, May 1 2015
#92: What if I want to save the image to the server? (Assuming we trust the user)
To #93: yes, `toDataURL` can be used in that case, too.  `toBlob` is primarily of interest for letting the image encoding happen asynchronously.
#94 - that is no longer the primary interest. We now simply need toBlobSync so we can immediately work with a Blob instead of an in memory base64 string.
Comment 96 by m...@jacobian.se, May 1 2015
I don't know about you guys but uploading a base64 string instead of the raw image data just feelings wrong...
#96: See comments #61, #57, and/or #49 for how to emulate or polyfill `toBlob` using `toDataURL`.  All of these methods take the data URI and convert it into a blob.

See comment #48 if you really want to upload "raw image data" :)

#96

So why you just do not upload it as a raw image? It won't be a lot faster if guys will implement it in C/C++ for you. There are already solutions written for sync toBlob. If people just want sync version of it, then I think this bug is correctly marked as "WontFix", since implementing it does not make any sense (except you are planning to handle images >20Mp, see webkit bug) because you still be required to use polyfill to get toBlob working across all browser. 
As I posted earlier, other vendors support blob based canvas export. Microsoft has a sync version with an ms prefix.

There is significant overhead in using toDataUrl vs toblob
to #99

Only Gecko supports it in full manner. MS has it, but it even lacks quality params for jpeg, so once you need to manipulation with jpeg, then should fallback to data: url in IE too. Anyway, you are saying "other" like there are 10 vendors vs only Google who do not want to implement it. The idea here what it might be implemented, but it's not Pr-1 or even 2 since all works just fine few years already with with transforming data: url to blob via JS.
Owner: xlai@chromium.org
Status: Assigned
Re-opening this issue, with recent improvements to the rendering architecture and the Blink scheduler this feature can be implemented in ways that avoid janking the main thread and avoid making a safety copy of the pixel buffer. So this feature can now be implemented in Chrome in a way that will deliver a significant improvement vs. toDataURL
Yay!!!!!  You rock Juno!!!
Comment 103 by Deleted ...@, Jul 20 2015
Great news, thanx. 
Comment 104 by Deleted ...@, Jul 21 2015
Wihooo! Great news!
Great news! thanx!
Comment 106 by vie...@gmail.com, Jul 29 2015
This is amazing
Labels: Hotlist-GPU-Fixit
Labels: -Type-Bug -Hotlist-GPU-Fixit Type-Launch-OWP
Comment 109 by xlai@chromium.org, Aug 20 2015
Status: Started
Comment 110 Deleted
Comment 111 Deleted
Project Member Comment 112 by bugdroid1@chromium.org, Aug 27 2015
The following revision refers to this bug:
  http://src.chromium.org/viewvc/blink?view=rev&rev=201327

------------------------------------------------------------------
r201327 | xlai@chromium.org | 2015-08-27T19:24:30.132404Z

Changed paths:
   A http://src.chromium.org/viewvc/blink/trunk/Source/core/fileapi/FileCallback.h?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/platform/graphics/ImageBuffer.h?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/modules/modules.gypi?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-maximum-quality.html?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-defaultpng.html?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-medium-quality.html?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/html/HTMLCanvasElement.h?r1=201327&r2=201326&pathrev=201327
   D http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/FileCallback.idl?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/fileapi/File.cpp?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-webp-maximum-quality.html?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/FileSystemCallbacks.cpp?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/DOMFileSystem.cpp?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/Source/core/fileapi/FileCallback.idl?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/LayoutTests/TestExpectations?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/html/HTMLCanvasElement.idl?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-case-insensitive-mimetype-expected.txt?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/platform/graphics/ImageBuffer.cpp?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/LayoutTests/webexposed/global-interface-listing-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/core.gypi?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/html/HTMLCanvasElement.cpp?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-case-insensitive-mimetype.html?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/LayoutTests/http/tests/security/canvas-read-blocked-by-setting.html?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/core/fileapi/File.h?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/LayoutTests/webexposed/element-instance-property-listing-expected.txt?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-defaultpng-expected.txt?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/InspectorFileSystemAgent.cpp?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.txt?r1=201327&r2=201326&pathrev=201327
   M http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/FileEntry.cpp?r1=201327&r2=201326&pathrev=201327
   D http://src.chromium.org/viewvc/blink/trunk/Source/modules/filesystem/FileCallback.h?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201327&r2=201326&pathrev=201327
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201327&r2=201326&pathrev=201327

The toBlob method in HTMLCanvasElement has been implemented.

Changes include:
(1) HTMLCanvasElement: 

The toBlob function is implemented in a similar fashion as the existing toDataURL function, taking in parameters like mimeType and qualityArgument. It has an additional argument FileCallback which accepts user-defined callback function.

(2) ImageDataBuffer:

encodeImage is made public.

(3) File:

A new create factory method is added to allow HTMLCanvasElement to create a new File object using the blob data. File object is a subtype of Blob object; it has two additional attributes -- name, last modification time -- as compared to Blob. We use empty string and current time to fill in these two attributes; FF creates the latter attribute in the same way.

(4) FileCallback: 

Moved from module/ to core/. 



BUG=67587

Review URL: https://codereview.chromium.org/1257253004
-----------------------------------------------------------------
Project Member Comment 113 by bugdroid1@chromium.org, Aug 28 2015
The following revision refers to this bug:
  http://src.chromium.org/viewvc/blink?view=rev&rev=201345

------------------------------------------------------------------
r201345 | joelo@chromium.org | 2015-08-27T23:56:07.439033Z

Changed paths:
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   M http://src.chromium.org/viewvc/blink/trunk/LayoutTests/TestExpectations?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   D http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png?r1=201345&r2=201344&pathrev=201345
   A http://src.chromium.org/viewvc/blink/trunk/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png?r1=201345&r2=201344&pathrev=201345

Auto-rebaseline for r201327

http://src.chromium.org/viewvc/blink?view=revision&revision=201327

BUG=67587
TBR=xlai@chromium.org

Review URL: https://codereview.chromium.org/1313183005 .
-----------------------------------------------------------------
So, is this going to show up in Chromium, Chrome Canary, Chrome? #112 says "The toBlob method in HTMLCanvasElement has been implemented," but I see that there are 2 Blocking issues, 523414 & 523417, so it's confusing whether this is released or if we're still being kept waiting. Could someone please clarify?
Comment 115 by xlai@chromium.org, Sep 14 2015
To #114: The implementation is not fully completed. It will not be released in the next Chrome Canary because now it's still marked as an experimental feature. This is why this issue is still not closed.
Thanx, xlai. I'd love to see this in Chrome, since the only thing in the wild implementing it is FF. FF is the only browser I've been able to get to save my composites with that actually saves everything. toDataURL won't behave as it is supposed to, even though my canvas shows in a browser properly, the saves are incomplete (as in, last operations just don't come through) on all the browsers, including FF. Maybe its just me doing something wrong, IDK, but toBlob rocks it.
If anyone wants to try it out in order to provide early feedback before the feature is fully shipped (which is always appreciated), just navigate to "chrome://flags" and enable "Experimental Canvas Features". That will unlock the experimental toBlob implementation in Chrome 47 (currently in Canary).

There is still some work regarding perfomance that needs to be completed before the feature can be shipped, but it should be functional at this point.  In particular, please be on the lookout for incompatibilies with other implementations (FireFox), and report them ASAP.  Thanks!
I have an app we wrote for a client that uses toBlob on Firefox, I'd be happy to test this, but I've never loaded a dev version of Chrome.  I use Windows, can you point me to a download that I can use to test this?

Joey 
Canary is here: https://www.google.com/chrome/browser/canary.html
It can live alongside a regular Chrome installation (will not clobber). It auto-updates daily, more or less, so if you are on a slow or limited internet connection, you may want to uninstall when done.
I'm getting entirely black images on 47.0.2503.0 / Linux.
@acmesquares: please file bug, attach code that reproduces the problem (a test html file) and add xlai@ and myself to the CC list. Thanks.
@junov -
Only project members can add people to the CC list. :(

@acmesquares -
Just post a comment with the new issue number here. :(
Ok it's not toBlob
Something else in "Experimental Canvas Features" is causing my problem. Is there a list of which features this flag currently switches?
These are the current Experimental Canvas Features:

CanvasPattern.setTransform
HTMLCanvasElement.toBlob
CanvasRenderingContext2D.currentTransform
CanvasRenderingContext2D.filter
CanvasRenderingContext2D.direction
CanvasRenderingContext2D.scrollPathIntoView
CanvasRenderingContext2D.isContextLost
CanvasRenderingContext2D HitRegion APIs
Path2D.addPath
TextMetrics : all metrics other than width
ImageBitmap interface
contextlost/contextrestored events on 2D canvas




You can also just create a new bug without knowing the exact cause. Just attach a sample html files and state that it misbehaves when experimentCanvasFeatures are enabled. We can figure it out from there.
Comment 126 Deleted
Was able to isolate: https://code.google.com/p/chromium/issues/detail?id=532148

Also the main scrollbar disappeared with experimentCanvasFeatures on while scrolling, but I wasn't able to reliably reproduce that.
Project Member Comment 128 by bugdroid1@chromium.org, Sep 25 2015
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/9dcdf861954dd8294faf3eefde89ea228f99c322

commit 9dcdf861954dd8294faf3eefde89ea228f99c322
Author: xlai <xlai@chromium.org>
Date: Fri Sep 25 21:05:24 2015

Implement Asynchronous image encoding for Canvas.toBlob

Main thread creates a new thread to carry out the computation-intensive asynchronous image encoding
operation. Afterwards the encoded image is passed back to the main thread to create blob and invoke user
callback.

Empty blob is passed to user callback in the senarios when the canvas has zero pixels or when the image
encoding fails.

This code review issue continues from the previous issue at https://codereview.chromium.org/1331443009/
before the blink and chromium are merged.

BUG=523414
BUG=67587

Review URL: https://codereview.chromium.org/1355333005

Cr-Commit-Position: refs/heads/master@{#350910}

[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-jpeg-expected.txt
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-jpeg.html
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-webp-expected.txt
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-webp.html
[add] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/LayoutTests/fast/canvas/script-tests/canvas-toBlob-toDataURL-race.js
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/core/fileapi/File.cpp
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/core/fileapi/File.h
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
[modify] http://crrev.com/9dcdf861954dd8294faf3eefde89ea228f99c322/third_party/WebKit/Source/platform/graphics/ImageBuffer.h

Blocking: -chromium:523414
Blockedon: chromium:523414
Blockedon: chromium:567887
Comment 132 Deleted
Comment 133 by phil...@opera.com, Dec 10 2015
The Intent to Ship this on blink-dev now as 3 LGTMs:
https://groups.google.com/a/chromium.org/d/msg/blink-dev/FnZBCN4t46w/qn3CtGa5BwAJ

Here are some spec changes that I hope will be implemented before this ships:
https://github.com/whatwg/html/pull/377 (callback shouldn't be nullable)
https://github.com/whatwg/html/issues/378 (use Blob, not File)

Also note that the callback should be a plain callback, not a callback interface. As currently implemented, this would actually work, which is not per spec:

canvas.toBlob({ handleEvent: function(blob) { ... } });
Blockedon: chromium:568603
"callback shouldn't be nullable" is being taken care of here: https://codereview.chromium.org/1496683005/

I created this issue for the blob vs. file thing: 568603
Just gonna say, thanks so much all of you who are working on this.  Sometimes I imagine my life without chrome, and it seems like such a dark and scary place :)
Project Member Comment 136 by bugdroid1@chromium.org, Dec 10 2015
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/de0c737213ae5df1ae88b666723639820432d19c

commit de0c737213ae5df1ae88b666723639820432d19c
Author: xlai <xlai@chromium.org>
Date: Thu Dec 10 18:22:41 2015

Make callback arg non-nullable on canvas.toBlob

Recent spec change (https://github.com/whatwg/html/pull/377) says that
toBlob() callback argument should be non-nullable.

BUG=67587

Review URL: https://codereview.chromium.org/1496683005

Cr-Commit-Position: refs/heads/master@{#364403}

[add] http://crrev.com/de0c737213ae5df1ae88b666723639820432d19c/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-invalid-expected.txt
[add] http://crrev.com/de0c737213ae5df1ae88b666723639820432d19c/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-invalid.html
[modify] http://crrev.com/de0c737213ae5df1ae88b666723639820432d19c/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl

Comment 137 by noel@chromium.org, Dec 11 2015
> #134 junov@ "I created this issue for the blob vs. file thing: issue 568603"

Thanks Justin, I added comments to issue 568603.  Let's get some implementation feedback to see if this very-late-in-the-game spec change makes sense.

Project Member Comment 138 by bugdroid1@chromium.org, Jan 25 2016
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/79bf7506c54ea3a11b55c39864f816cb16588bf4

commit 79bf7506c54ea3a11b55c39864f816cb16588bf4
Author: xlai <xlai@chromium.org>
Date: Mon Jan 25 17:35:02 2016

Ship canvas.toBlob

With 3 L-g-t-m from the API owners
(https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/FnZBCN4t46w),
this feature is ready to ship.

Patches that make corrections based on specification change
 (https://codereview.chromium.org/1496683005 and
https://codereview.chromium.org/1609313002/) have been landed. Also, the
concern of having the threaded implementation (as compared to the idle-periods
implementation) have been addressed and fixed by using a shared thread pool in
Blink (https://code.google.com/p/chromium/issues/detail?id=567887).

BUG=67587

Review URL: https://codereview.chromium.org/1617063003

Cr-Commit-Position: refs/heads/master@{#371256}

[modify] http://crrev.com/79bf7506c54ea3a11b55c39864f816cb16588bf4/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
[modify] http://crrev.com/79bf7506c54ea3a11b55c39864f816cb16588bf4/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
[modify] http://crrev.com/79bf7506c54ea3a11b55c39864f816cb16588bf4/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl

Are we ready to mark as Fixed?
Status: Fixed
Yep. It is currently enabled for shipping in Chrome 50.
I will update the feature dashboard.

Sign in to add a comment