UNPKG

12.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5// TODO: including these in blob-util.ts causes typedoc to generate docs for them,
6// even with --excludePrivate ¯\_(ツ)_/¯
7/** @private */
8function loadImage(src, crossOrigin) {
9 return new Promise(function (resolve, reject) {
10 var img = new Image();
11 if (crossOrigin) {
12 img.crossOrigin = crossOrigin;
13 }
14 img.onload = function () {
15 resolve(img);
16 };
17 img.onerror = reject;
18 img.src = src;
19 });
20}
21/** @private */
22function imgToCanvas(img) {
23 var canvas = document.createElement('canvas');
24 canvas.width = img.width;
25 canvas.height = img.height;
26 // copy the image contents to the canvas
27 var context = canvas.getContext('2d');
28 context.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
29 return canvas;
30}
31
32/* global Promise, Image, Blob, FileReader, atob, btoa,
33 BlobBuilder, MSBlobBuilder, MozBlobBuilder, WebKitBlobBuilder, webkitURL */
34/**
35 * Shim for
36 * [`new Blob()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob.Blob)
37 * to support
38 * [older browsers that use the deprecated `BlobBuilder` API](http://caniuse.com/blob).
39 *
40 * Example:
41 *
42 * ```js
43 * var myBlob = blobUtil.createBlob(['hello world'], {type: 'text/plain'});
44 * ```
45 *
46 * @param parts - content of the Blob
47 * @param properties - usually `{type: myContentType}`,
48 * you can also pass a string for the content type
49 * @returns Blob
50 */
51function createBlob(parts, properties) {
52 parts = parts || [];
53 properties = properties || {};
54 if (typeof properties === 'string') {
55 properties = { type: properties }; // infer content type
56 }
57 try {
58 return new Blob(parts, properties);
59 }
60 catch (e) {
61 if (e.name !== 'TypeError') {
62 throw e;
63 }
64 var Builder = typeof BlobBuilder !== 'undefined'
65 ? BlobBuilder : typeof MSBlobBuilder !== 'undefined'
66 ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined'
67 ? MozBlobBuilder : WebKitBlobBuilder;
68 var builder = new Builder();
69 for (var i = 0; i < parts.length; i += 1) {
70 builder.append(parts[i]);
71 }
72 return builder.getBlob(properties.type);
73 }
74}
75/**
76 * Shim for
77 * [`URL.createObjectURL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL)
78 * to support browsers that only have the prefixed
79 * `webkitURL` (e.g. Android <4.4).
80 *
81 * Example:
82 *
83 * ```js
84 * var myUrl = blobUtil.createObjectURL(blob);
85 * ```
86 *
87 * @param blob
88 * @returns url
89 */
90function createObjectURL(blob) {
91 return (typeof URL !== 'undefined' ? URL : webkitURL).createObjectURL(blob);
92}
93/**
94 * Shim for
95 * [`URL.revokeObjectURL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL.revokeObjectURL)
96 * to support browsers that only have the prefixed
97 * `webkitURL` (e.g. Android <4.4).
98 *
99 * Example:
100 *
101 * ```js
102 * blobUtil.revokeObjectURL(myUrl);
103 * ```
104 *
105 * @param url
106 */
107function revokeObjectURL(url) {
108 return (typeof URL !== 'undefined' ? URL : webkitURL).revokeObjectURL(url);
109}
110/**
111 * Convert a `Blob` to a binary string.
112 *
113 * Example:
114 *
115 * ```js
116 * blobUtil.blobToBinaryString(blob).then(function (binaryString) {
117 * // success
118 * }).catch(function (err) {
119 * // error
120 * });
121 * ```
122 *
123 * @param blob
124 * @returns Promise that resolves with the binary string
125 */
126function blobToBinaryString(blob) {
127 return new Promise(function (resolve, reject) {
128 var reader = new FileReader();
129 var hasBinaryString = typeof reader.readAsBinaryString === 'function';
130 reader.onloadend = function () {
131 var result = reader.result || '';
132 if (hasBinaryString) {
133 return resolve(result);
134 }
135 resolve(arrayBufferToBinaryString(result));
136 };
137 reader.onerror = reject;
138 if (hasBinaryString) {
139 reader.readAsBinaryString(blob);
140 }
141 else {
142 reader.readAsArrayBuffer(blob);
143 }
144 });
145}
146/**
147 * Convert a base64-encoded string to a `Blob`.
148 *
149 * Example:
150 *
151 * ```js
152 * var blob = blobUtil.base64StringToBlob(base64String);
153 * ```
154 * @param base64 - base64-encoded string
155 * @param type - the content type (optional)
156 * @returns Blob
157 */
158function base64StringToBlob(base64, type) {
159 var parts = [binaryStringToArrayBuffer(atob(base64))];
160 return type ? createBlob(parts, { type: type }) : createBlob(parts);
161}
162/**
163 * Convert a binary string to a `Blob`.
164 *
165 * Example:
166 *
167 * ```js
168 * var blob = blobUtil.binaryStringToBlob(binaryString);
169 * ```
170 *
171 * @param binary - binary string
172 * @param type - the content type (optional)
173 * @returns Blob
174 */
175function binaryStringToBlob(binary, type) {
176 return base64StringToBlob(btoa(binary), type);
177}
178/**
179 * Convert a `Blob` to a binary string.
180 *
181 * Example:
182 *
183 * ```js
184 * blobUtil.blobToBase64String(blob).then(function (base64String) {
185 * // success
186 * }).catch(function (err) {
187 * // error
188 * });
189 * ```
190 *
191 * @param blob
192 * @returns Promise that resolves with the binary string
193 */
194function blobToBase64String(blob) {
195 return blobToBinaryString(blob).then(btoa);
196}
197/**
198 * Convert a data URL string
199 * (e.g. `'data:image/png;base64,iVBORw0KG...'`)
200 * to a `Blob`.
201 *
202 * Example:
203 *
204 * ```js
205 * var blob = blobUtil.dataURLToBlob(dataURL);
206 * ```
207 *
208 * @param dataURL - dataURL-encoded string
209 * @returns Blob
210 */
211function dataURLToBlob(dataURL) {
212 var type = dataURL.match(/data:([^;]+)/)[1];
213 var base64 = dataURL.replace(/^[^,]+,/, '');
214 var buff = binaryStringToArrayBuffer(atob(base64));
215 return createBlob([buff], { type: type });
216}
217/**
218 * Convert a `Blob` to a data URL string
219 * (e.g. `'data:image/png;base64,iVBORw0KG...'`).
220 *
221 * Example:
222 *
223 * ```js
224 * var dataURL = blobUtil.blobToDataURL(blob);
225 * ```
226 *
227 * @param blob
228 * @returns Promise that resolves with the data URL string
229 */
230function blobToDataURL(blob) {
231 return blobToBase64String(blob).then(function (base64String) {
232 return 'data:' + blob.type + ';base64,' + base64String;
233 });
234}
235/**
236 * Convert an image's `src` URL to a data URL by loading the image and painting
237 * it to a `canvas`.
238 *
239 * Note: this will coerce the image to the desired content type, and it
240 * will only paint the first frame of an animated GIF.
241 *
242 * Examples:
243 *
244 * ```js
245 * blobUtil.imgSrcToDataURL('http://mysite.com/img.png').then(function (dataURL) {
246 * // success
247 * }).catch(function (err) {
248 * // error
249 * });
250 * ```
251 *
252 * ```js
253 * blobUtil.imgSrcToDataURL('http://some-other-site.com/img.jpg', 'image/jpeg',
254 * 'Anonymous', 1.0).then(function (dataURL) {
255 * // success
256 * }).catch(function (err) {
257 * // error
258 * });
259 * ```
260 *
261 * @param src - image src
262 * @param type - the content type (optional, defaults to 'image/png')
263 * @param crossOrigin - for CORS-enabled images, set this to
264 * 'Anonymous' to avoid "tainted canvas" errors
265 * @param quality - a number between 0 and 1 indicating image quality
266 * if the requested type is 'image/jpeg' or 'image/webp'
267 * @returns Promise that resolves with the data URL string
268 */
269function imgSrcToDataURL(src, type, crossOrigin, quality) {
270 type = type || 'image/png';
271 return loadImage(src, crossOrigin).then(imgToCanvas).then(function (canvas) {
272 return canvas.toDataURL(type, quality);
273 });
274}
275/**
276 * Convert a `canvas` to a `Blob`.
277 *
278 * Examples:
279 *
280 * ```js
281 * blobUtil.canvasToBlob(canvas).then(function (blob) {
282 * // success
283 * }).catch(function (err) {
284 * // error
285 * });
286 * ```
287 *
288 * Most browsers support converting a canvas to both `'image/png'` and `'image/jpeg'`. You may
289 * also want to try `'image/webp'`, which will work in some browsers like Chrome (and in other browsers, will just fall back to `'image/png'`):
290 *
291 * ```js
292 * blobUtil.canvasToBlob(canvas, 'image/webp').then(function (blob) {
293 * // success
294 * }).catch(function (err) {
295 * // error
296 * });
297 * ```
298 *
299 * @param canvas - HTMLCanvasElement
300 * @param type - the content type (optional, defaults to 'image/png')
301 * @param quality - a number between 0 and 1 indicating image quality
302 * if the requested type is 'image/jpeg' or 'image/webp'
303 * @returns Promise that resolves with the `Blob`
304 */
305function canvasToBlob(canvas, type, quality) {
306 if (typeof canvas.toBlob === 'function') {
307 return new Promise(function (resolve) {
308 canvas.toBlob(resolve, type, quality);
309 });
310 }
311 return Promise.resolve(dataURLToBlob(canvas.toDataURL(type, quality)));
312}
313/**
314 * Convert an image's `src` URL to a `Blob` by loading the image and painting
315 * it to a `canvas`.
316 *
317 * Note: this will coerce the image to the desired content type, and it
318 * will only paint the first frame of an animated GIF.
319 *
320 * Examples:
321 *
322 * ```js
323 * blobUtil.imgSrcToBlob('http://mysite.com/img.png').then(function (blob) {
324 * // success
325 * }).catch(function (err) {
326 * // error
327 * });
328 * ```
329 *
330 * ```js
331 * blobUtil.imgSrcToBlob('http://some-other-site.com/img.jpg', 'image/jpeg',
332 * 'Anonymous', 1.0).then(function (blob) {
333 * // success
334 * }).catch(function (err) {
335 * // error
336 * });
337 * ```
338 *
339 * @param src - image src
340 * @param type - the content type (optional, defaults to 'image/png')
341 * @param crossOrigin - for CORS-enabled images, set this to
342 * 'Anonymous' to avoid "tainted canvas" errors
343 * @param quality - a number between 0 and 1 indicating image quality
344 * if the requested type is 'image/jpeg' or 'image/webp'
345 * @returns Promise that resolves with the `Blob`
346 */
347function imgSrcToBlob(src, type, crossOrigin, quality) {
348 type = type || 'image/png';
349 return loadImage(src, crossOrigin).then(imgToCanvas).then(function (canvas) {
350 return canvasToBlob(canvas, type, quality);
351 });
352}
353/**
354 * Convert an `ArrayBuffer` to a `Blob`.
355 *
356 * Example:
357 *
358 * ```js
359 * var blob = blobUtil.arrayBufferToBlob(arrayBuff, 'audio/mpeg');
360 * ```
361 *
362 * @param buffer
363 * @param type - the content type (optional)
364 * @returns Blob
365 */
366function arrayBufferToBlob(buffer, type) {
367 return createBlob([buffer], type);
368}
369/**
370 * Convert a `Blob` to an `ArrayBuffer`.
371 *
372 * Example:
373 *
374 * ```js
375 * blobUtil.blobToArrayBuffer(blob).then(function (arrayBuff) {
376 * // success
377 * }).catch(function (err) {
378 * // error
379 * });
380 * ```
381 *
382 * @param blob
383 * @returns Promise that resolves with the `ArrayBuffer`
384 */
385function blobToArrayBuffer(blob) {
386 return new Promise(function (resolve, reject) {
387 var reader = new FileReader();
388 reader.onloadend = function () {
389 var result = reader.result || new ArrayBuffer(0);
390 resolve(result);
391 };
392 reader.onerror = reject;
393 reader.readAsArrayBuffer(blob);
394 });
395}
396/**
397 * Convert an `ArrayBuffer` to a binary string.
398 *
399 * Example:
400 *
401 * ```js
402 * var myString = blobUtil.arrayBufferToBinaryString(arrayBuff)
403 * ```
404 *
405 * @param buffer - array buffer
406 * @returns binary string
407 */
408function arrayBufferToBinaryString(buffer) {
409 var binary = '';
410 var bytes = new Uint8Array(buffer);
411 var length = bytes.byteLength;
412 var i = -1;
413 while (++i < length) {
414 binary += String.fromCharCode(bytes[i]);
415 }
416 return binary;
417}
418/**
419 * Convert a binary string to an `ArrayBuffer`.
420 *
421 * ```js
422 * var myBuffer = blobUtil.binaryStringToArrayBuffer(binaryString)
423 * ```
424 *
425 * @param binary - binary string
426 * @returns array buffer
427 */
428function binaryStringToArrayBuffer(binary) {
429 var length = binary.length;
430 var buf = new ArrayBuffer(length);
431 var arr = new Uint8Array(buf);
432 var i = -1;
433 while (++i < length) {
434 arr[i] = binary.charCodeAt(i);
435 }
436 return buf;
437}
438
439exports.createBlob = createBlob;
440exports.createObjectURL = createObjectURL;
441exports.revokeObjectURL = revokeObjectURL;
442exports.blobToBinaryString = blobToBinaryString;
443exports.base64StringToBlob = base64StringToBlob;
444exports.binaryStringToBlob = binaryStringToBlob;
445exports.blobToBase64String = blobToBase64String;
446exports.dataURLToBlob = dataURLToBlob;
447exports.blobToDataURL = blobToDataURL;
448exports.imgSrcToDataURL = imgSrcToDataURL;
449exports.canvasToBlob = canvasToBlob;
450exports.imgSrcToBlob = imgSrcToBlob;
451exports.arrayBufferToBlob = arrayBufferToBlob;
452exports.blobToArrayBuffer = blobToArrayBuffer;
453exports.arrayBufferToBinaryString = arrayBufferToBinaryString;
454exports.binaryStringToArrayBuffer = binaryStringToArrayBuffer;