UNPKG

5.31 kBJavaScriptView Raw
1
2import { BunnyFile } from './file';
3
4/**
5 * @component BunnyImage
6 * Wrapper for Image object representing <img> tag, uses Canvas and BunnyFile
7 *
8 */
9export const BunnyImage = {
10
11 IMG_CONVERT_TYPE: 'image/jpeg',
12 IMG_QUALITY: 0.7,
13
14 // SECTION: get Image object via different sources
15
16 /**
17 * Downloads image by any URL or converts from Blob, should work also for non-CORS domains
18 *
19 * @param {String|Blob} urlOrBlob
20 * @returns {Promise} success(Image object), fail(error)
21 */
22 getImage(urlOrBlob) {
23 if (typeof urlOrBlob === 'string') {
24 return this.getImageByURL(urlOrBlob);
25 } else {
26 return this.getImageByBlob(urlOrBlob);
27 }
28 },
29
30 /**
31 * Downloads image by any URL, should work also for non-CORS domains
32 *
33 * @param {String} URL
34 * @returns {Promise} success(Image object), fail(error)
35 */
36 getImageByURL(URL) {
37 return this._toImagePromise(URL, true);
38 },
39
40 _toImagePromise(src, crossOrigin = false) {
41 const img = new Image;
42 const p = new Promise( (ok, fail) => {
43 img.onload = () => {
44 ok(img);
45 };
46 img.onerror = (e) => {
47 fail(e);
48 }
49 });
50 if (crossOrigin) {
51 img.crossOrigin = 'Anonymous';
52 }
53 img.src = src;
54 return p;
55 },
56
57 getImageByBlob(blob) {
58 const url = BunnyFile.getBlobLocalURL(blob);
59 return this._toImagePromise(url);
60 },
61
62 getImageByBase64(base64) {
63 const url = base64;
64 return this._toImagePromise(url);
65 },
66
67 getImageByCanvas(canvas) {
68 const url = canvas.toDataURL(this.IMG_CONVERT_TYPE, this.IMG_QUALITY);
69 return this._toImagePromise(url);
70 },
71
72
73
74
75 // SECTION:: create different sources from Image object
76
77 imageToCanvas(img, width = null, height = null) {
78 if (!img.complete) {
79 throw new Error('Can not create canvas from Image. Image is not loaded yet.');
80 }
81 const canvas = document.createElement("canvas");
82 if (width === null && height === null) {
83 canvas.width = img.naturalWidth;
84 canvas.height = img.naturalHeight;
85 canvas.getContext("2d").drawImage(img, 0, 0);
86 } else {
87 canvas.width = width;
88 canvas.height = height;
89 canvas.getContext("2d").drawImage(img, 0, 0, width, height);
90 }
91 return canvas;
92 },
93
94 /**
95 *
96 * @param {Image|HTMLImageElement} img
97 * @param {Number?} width
98 * @param {Number?} height
99 * @returns {string}
100 */
101 imageToBase64(img, width = null, height = null) {
102 return this.imageToCanvas(img, width, height).toDataURL(this.IMG_CONVERT_TYPE, this.IMG_QUALITY);
103 },
104
105 /**
106 *
107 * @param {Image|HTMLImageElement} img
108 * @param {Number?} width
109 * @param {Number?} height
110 * @returns {Blob}
111 */
112 imageToBlob(img, width = null, height = null) {
113 return BunnyFile.base64ToBlob(this.imageToBase64(img, width, height));
114 },
115
116
117
118
119 // SECTION: basic Image statistics and info functions
120
121 getImageURL(img) {
122 return img.src;
123 },
124
125 getImageWidth(img) {
126 if (!img.complete) {
127 throw new Error('Can not get Image.width. Image is not loaded yet.');
128 }
129 return img.width;
130 },
131
132 getImageHeight(img) {
133 if (!img.complete) {
134 throw new Error('Can not get Image.height. Image is not loaded yet.');
135 }
136 return img.height;
137 },
138
139
140
141
142 // SECTION: basic Image data math functions
143
144 getImageNewAspectSizes(img, max_width, max_height) {
145 const img_width = this.getImageWidth(img);
146 const img_height = this.getImageHeight(img);
147 if (img_width === 0 || img_height === 0) {
148 throw new Error('Image width or height is 0 in BunnyImage.getImageNewAspectSizes().')
149 }
150 const ratio = Math.min(max_width / img_width, max_height / img_height);
151
152 return {
153 width: Math.floor(img_width * ratio),
154 height: Math.floor(img_height * ratio)
155 };
156 },
157
158
159
160
161
162 // SECTION: basic Image manipulation
163 // returns canvas
164
165 /**
166 * Resize image
167 * @param {Image} img
168 * @param {Number} max_width
169 * @param {Number} max_height
170 * @returns {Promise} success(Image), fail(error)
171 */
172 resizeImage(img, max_width, max_height) {
173 const sizes = this.getImageNewAspectSizes(img, max_width, max_height);
174 const width = sizes.width;
175 const height = sizes.height;
176 const canvas = this.imageToCanvas(img, width, height);
177 return canvas;
178 //return this.getImageByCanvas(canvas);
179 },
180
181 resizeCanvas(canvas, width, height = null) {
182 if (height === null) height = width;
183 const tmpCanvas = document.createElement('canvas');
184 const tmpCtx = tmpCanvas.getContext('2d');
185 tmpCanvas.width = width;
186 tmpCanvas.height = height;
187 tmpCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, width, height);
188 return tmpCanvas;
189 },
190
191 crop(img, x, y, width, height = null) {
192 if (height === null) height = width;
193 const proportion = img.naturalWidth / img.clientWidth;
194 const canvas = document.createElement('canvas');
195 const sizeX = width * proportion;
196 const sizeY = height * proportion;
197 canvas.width = sizeX;
198 canvas.height = sizeY;
199 const ctx = canvas.getContext('2d');
200 ctx.drawImage(img, x * proportion, y * proportion, sizeX, sizeY, 0, 0, sizeX, sizeY);
201 return canvas;
202 },
203
204 cropByCursor(img, cursor) {
205 return this.crop(img, cursor.offsetLeft, cursor.offsetTop, cursor.clientWidth, cursor.clientHeight);
206 }
207
208};