UNPKG

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