1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
---
title: HTMLCanvasElement.toBlob()
slug: Web/API/HTMLCanvasElement/toBlob
translation_of: Web/API/HTMLCanvasElement/toBlob
---
<div>
<div>
<div>{{APIRef("Canvas API")}}</div>
</div>
</div>
<p>EL metodo <strong><code>HTMLCanvasElement.toBlob()</code></strong> crea un objeto {{domxref("Blob")}} que representa la imagen contenida en el canvas; este archivo puede ser cacheado en el disco oo guardado en la memoria a desicion del user agent. Si la propiedad <code>type</code> no se especifica el tipo de la imagen será <code>image/png</code>. La imagen creada tiene una resolución de 96dpi.<br>
El tercer argumento es usado con las imagenes <code>image/jpeg</code> para especificar la calidad de salida.</p>
<h2 id="Syntax">Syntax</h2>
<pre class="syntaxbox"><var>void <em>canvas</em>.toBlob(<em>callback</em>, <em>type</em>, <em>encoderOptions</em>);</var>
</pre>
<h3 id="Parameters">Parameters</h3>
<dl>
<dt>callback</dt>
<dd>A callback function with the resulting {{domxref("Blob")}} object as a single argument.</dd>
<dt><code>type</code> {{optional_inline}}</dt>
<dd>A {{domxref("DOMString")}} indicating the image format. The default type is <code>image/png</code>.</dd>
<dt><code>encoderOptions</code> {{optional_inline}}</dt>
<dd>A {{jsxref("Number")}} between <code>0</code> and <code>1</code> indicating image quality if the requested type is <code>image/jpeg </code>or <code>image/webp</code>. If this argument is anything else, the default value for image quality is used. Other arguments are ignored.</dd>
</dl>
<h3 id="Return_value">Return value</h3>
<p>None.</p>
<h2 id="Examples">Examples</h2>
<h3 id="Getting_a_file_representing_the_canvas">Getting a file representing the canvas</h3>
<p>Once you have drawn content into a canvas, you can convert it into a file of any supported image format. The code snippet below, for example, takes the image in the {{HTMLElement("canvas")}} element whose ID is "canvas", obtains a copy of it as a PNG image, then appends a new {{HTMLElement("img")}} element to the document, whose source image is the one created using the canvas.</p>
<pre class="brush: js">var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob) {
var newImg = document.createElement("img"),
url = URL.createObjectURL(blob);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
});
</pre>
<p>Note that here we're creating a PNG image; if you add a second parameter to the <code>toBlob()</code> call, you can specify the image type. For example, to get the image in JPEG format:</p>
<pre class="brush: js"> canvas.toBlob(function(blob){...}, "image/jpeg", 0.95); // JPEG at 95% quality</pre>
<div>
<h3 id="A_way_to_convert_a_canvas_to_an_ico_(Mozilla_only)">A way to convert a canvas to an ico (Mozilla only)</h3>
<p>This uses <code>-moz-parse</code> to convert the canvas to ico. Windows XP doesn't support converting from PNG to ico, so it uses bmp instead. A download link is created by setting the download attribute. The value of the download attribute is the name it will use as the file name.</p>
<pre class="brush: js">var canvas = document.getElementById("canvas");
var d = canvas.width;
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(d / 2, 0);
ctx.lineTo(d, d);
ctx.lineTo(0, d);
ctx.closePath();
ctx.fillStyle = "yellow";
ctx.fill();
function blobCallback(iconName) {
return function(b) {
var a = document.createElement("a");
a.textContent = "Download";
document.body.appendChild(a);
a.style.display = "block";
a.download = iconName + ".ico";
a.href = window.URL.createObjectURL(b);
}
}
canvas.toBlob(blobCallback('passThisString'), 'image/vnd.microsoft.icon',
'-moz-parse-options:format=bmp;bpp=32');</pre>
</div>
<h3 id="Save_toBlob_to_disk_with_OS.File_(chromeadd-on_context_only)">Save toBlob to disk with OS.File (chrome/add-on context only)</h3>
<div class="note">
<p>This technique saves it to the desktop and is only useful in Firefox chrome context or add-on code as OS APIs are not present on web sites.</p>
</div>
<pre class="brush: js">var canvas = document.getElementById("canvas");
var d = canvas.width;
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(d / 2, 0);
ctx.lineTo(d, d);
ctx.lineTo(0, d);
ctx.closePath();
ctx.fillStyle = "yellow";
ctx.fill();
function blobCallback(iconName) {
return function(b) {
var r = new FileReader();
r.onloadend = function () {
// r.result contains the ArrayBuffer.
Cu.import('resource://gre/modules/osfile.jsm');
var writePath = OS.Path.join(OS.Constants.Path.desktopDir,
iconName + '.ico');
var promise = OS.File.writeAtomic(writePath, new Uint8Array(r.result),
{tmpPath:writePath + '.tmp'});
promise.then(
function() {
console.log('successfully wrote file');
},
function() {
console.log('failure writing file')
}
);
};
r.readAsArrayBuffer(b);
}
}
canvas.toBlob(blobCallback('passThisString'), 'image/vnd.microsoft.icon',
'-moz-parse-options:format=bmp;bpp=32');</pre>
<h2 id="Polyfill">Polyfill</h2>
<p>A low performance polyfill based on toDataURL.</p>
<pre class="brush: js">if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {
var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);
for (var i=0; i<len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}
</pre>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('HTML WHATWG', "scripting.html#dom-canvas-toblob", "HTMLCanvasElement.toBlob")}}</td>
<td>{{Spec2('HTML WHATWG')}}</td>
<td>No change since the latest snapshot, {{SpecName('HTML5 W3C')}}</td>
</tr>
<tr>
<td>{{SpecName('HTML5.1', "scripting-1.html#dom-canvas-toblob", "HTMLCanvasElement.toBlob")}}</td>
<td>{{Spec2('HTML5.1')}}</td>
<td>No change</td>
</tr>
<tr>
<td>{{SpecName('HTML5 W3C', "scripting-1.html#dom-canvas-toblob", "HTMLCanvasElement.toBlob")}}</td>
<td>{{Spec2('HTML5 W3C')}}</td>
<td>Snapshot of the {{SpecName('HTML WHATWG')}} containing the initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<p>{{CompatibilityTable}}</p>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Basic support</td>
<td>{{CompatNo}}<sup>[1]</sup></td>
<td>{{CompatGeckoDesktop('19')}}</td>
<td>{{CompatIE(10)}}{{property_prefix("ms")}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatNo}}<sup>[2]</sup></td>
</tr>
<tr>
<td>Image quality parameter (jpeg)</td>
<td>{{CompatNo}}</td>
<td>{{CompatGeckoDesktop('25')}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatNo}}</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Chrome for Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td>{{CompatNo}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatGeckoMobile("19")}}</td>
<td>{{CompatUnknown}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatUnknown}}</td>
</tr>
<tr>
<td>Image quality parameter (jpeg)</td>
<td>{{CompatNo}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatGeckoMobile("25")}}</td>
<td>{{CompatUnknown}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatUnknown}}</td>
</tr>
</tbody>
</table>
</div>
<p>[1] Chrome does not implement this feature yet. See <a href="http://crbug.com/67587">bug 67587</a>.</p>
<p>[2] WebKit does not implement this feature yet. See {{WebKitBug("71270")}}.</p>
<h2 id="See_also">See also</h2>
<ul>
<li>The interface defining it, {{domxref("HTMLCanvasElement")}}.</li>
<li>{{domxref("Blob")}}</li>
</ul>
|