@webex/helper-image 2.59.2 → 2.59.3-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.js CHANGED
@@ -1,68 +1,68 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- /* eslint no-unused-vars: ["error", { "vars": "local" }] */
6
- // eslint-disable-next-line no-redeclare
7
-
8
- const {Buffer} = require('safe-buffer');
9
- const {parse} = require('exifr/dist/lite.umd');
10
-
11
- /**
12
- * Updates the image file with exif information, required to correctly rotate the image activity
13
- * @param {Object} file
14
- * @param {Object} options
15
- * @param {boolean} options.shouldNotAddExifData
16
- * @returns {Promise<Object>}
17
- */
18
- export function updateImageOrientation(file, options = {}) {
19
- return new Promise((resolve) => {
20
- const reader = new FileReader();
21
-
22
- reader.readAsArrayBuffer(file);
23
- reader.onload = function onload() {
24
- const arrayBuffer = reader.result;
25
- const buf = Buffer.from(arrayBuffer);
26
-
27
- resolve(buf);
28
- };
29
- }).then((buf) => {
30
- if (options.shouldNotAddExifData) {
31
- return buf;
32
- }
33
-
34
- return readExifData(file, buf);
35
- });
36
- }
37
-
38
- /**
39
- * Adds exif orientation information on the image file
40
- * @param {Object} file
41
- * @param {Object} buf
42
- * @returns {Promise<ExifImage>}
43
- */
44
- export async function readExifData(file, buf) {
45
- // For avatar images the file.type is set as image/jpeg, however for images shared in an activity file.mimeType is set as image/jpeg. Handling both conditions.
46
- if (file && (file.type === 'image/jpeg' || file.mimeType === 'image/jpeg')) {
47
- const exifData = await parse(buf, {translateValues: false});
48
-
49
- if (exifData) {
50
- const {Orientation, ExifImageHeight, ExifImageWidth} = exifData;
51
-
52
- file.orientation = Orientation;
53
- file.exifHeight = ExifImageHeight;
54
- file.exifWidth = ExifImageWidth;
55
-
56
- if (file.image) {
57
- file.image.orientation = Orientation;
58
- }
59
- }
60
- }
61
-
62
- return buf;
63
- }
64
-
65
- /* eslint-enable complexity */
66
-
67
- export {default as processImage} from './process-image';
68
- export {default as detectFileType} from './detect-filetype';
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ /* eslint no-unused-vars: ["error", { "vars": "local" }] */
6
+ // eslint-disable-next-line no-redeclare
7
+
8
+ const {Buffer} = require('safe-buffer');
9
+ const {parse} = require('exifr/dist/lite.umd');
10
+
11
+ /**
12
+ * Updates the image file with exif information, required to correctly rotate the image activity
13
+ * @param {Object} file
14
+ * @param {Object} options
15
+ * @param {boolean} options.shouldNotAddExifData
16
+ * @returns {Promise<Object>}
17
+ */
18
+ export function updateImageOrientation(file, options = {}) {
19
+ return new Promise((resolve) => {
20
+ const reader = new FileReader();
21
+
22
+ reader.readAsArrayBuffer(file);
23
+ reader.onload = function onload() {
24
+ const arrayBuffer = reader.result;
25
+ const buf = Buffer.from(arrayBuffer);
26
+
27
+ resolve(buf);
28
+ };
29
+ }).then((buf) => {
30
+ if (options.shouldNotAddExifData) {
31
+ return buf;
32
+ }
33
+
34
+ return readExifData(file, buf);
35
+ });
36
+ }
37
+
38
+ /**
39
+ * Adds exif orientation information on the image file
40
+ * @param {Object} file
41
+ * @param {Object} buf
42
+ * @returns {Promise<ExifImage>}
43
+ */
44
+ export async function readExifData(file, buf) {
45
+ // For avatar images the file.type is set as image/jpeg, however for images shared in an activity file.mimeType is set as image/jpeg. Handling both conditions.
46
+ if (file && (file.type === 'image/jpeg' || file.mimeType === 'image/jpeg')) {
47
+ const exifData = await parse(buf, {translateValues: false});
48
+
49
+ if (exifData) {
50
+ const {Orientation, ExifImageHeight, ExifImageWidth} = exifData;
51
+
52
+ file.orientation = Orientation;
53
+ file.exifHeight = ExifImageHeight;
54
+ file.exifWidth = ExifImageWidth;
55
+
56
+ if (file.image) {
57
+ file.image.orientation = Orientation;
58
+ }
59
+ }
60
+ }
61
+
62
+ return buf;
63
+ }
64
+
65
+ /* eslint-enable complexity */
66
+
67
+ export {default as processImage} from './process-image';
68
+ export {default as detectFileType} from './detect-filetype';
package/src/orient.js CHANGED
@@ -1,48 +1,48 @@
1
- /* eslint-disable complexity */
2
- /**
3
- * Rotates/flips the image on the canvas as per exif information
4
- * @param {Object} options(orientation: image exif orientation range from 1-8, img: Image object, x: start x-axis, y: start y-axis, width: width of the thumbnail, height: height of the thumbnail, ctx: canvas context)
5
- * @param {Object} file
6
- * @returns {Object}
7
- */
8
- export function orient(options, file) {
9
- const {width, height, ctx, img, orientation, x, y} = options;
10
-
11
- if (file && file.orientation && file.orientation !== 1) {
12
- // explanation of orientation:
13
- // https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
14
- switch (orientation) {
15
- case 2:
16
- // flip
17
- ctx.transform(-1, 0, 0, 1, width, 0);
18
- break;
19
- case 3:
20
- // rotateImage180
21
- ctx.transform(-1, 0, 0, -1, width, height);
22
- break;
23
- case 4:
24
- // rotate180AndFlipImage
25
- ctx.transform(1, 0, 0, -1, 0, height);
26
- break;
27
- case 5:
28
- // rotate90AndFlipImage
29
- ctx.transform(0, 1, 1, 0, 0, 0);
30
- break;
31
- case 6:
32
- // rotateImage90
33
- ctx.transform(0, 1, -1, 0, height, 0);
34
- break;
35
- case 7:
36
- // rotateNeg90AndFlipImage
37
- ctx.transform(0, -1, -1, 0, height, width);
38
- break;
39
- case 8:
40
- // rotateNeg90
41
- ctx.transform(0, -1, 1, 0, 0, width);
42
- break;
43
- default:
44
- break;
45
- }
46
- }
47
- ctx.drawImage(img, x, y, width, height);
48
- }
1
+ /* eslint-disable complexity */
2
+ /**
3
+ * Rotates/flips the image on the canvas as per exif information
4
+ * @param {Object} options(orientation: image exif orientation range from 1-8, img: Image object, x: start x-axis, y: start y-axis, width: width of the thumbnail, height: height of the thumbnail, ctx: canvas context)
5
+ * @param {Object} file
6
+ * @returns {Object}
7
+ */
8
+ export function orient(options, file) {
9
+ const {width, height, ctx, img, orientation, x, y} = options;
10
+
11
+ if (file && file.orientation && file.orientation !== 1) {
12
+ // explanation of orientation:
13
+ // https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
14
+ switch (orientation) {
15
+ case 2:
16
+ // flip
17
+ ctx.transform(-1, 0, 0, 1, width, 0);
18
+ break;
19
+ case 3:
20
+ // rotateImage180
21
+ ctx.transform(-1, 0, 0, -1, width, height);
22
+ break;
23
+ case 4:
24
+ // rotate180AndFlipImage
25
+ ctx.transform(1, 0, 0, -1, 0, height);
26
+ break;
27
+ case 5:
28
+ // rotate90AndFlipImage
29
+ ctx.transform(0, 1, 1, 0, 0, 0);
30
+ break;
31
+ case 6:
32
+ // rotateImage90
33
+ ctx.transform(0, 1, -1, 0, height, 0);
34
+ break;
35
+ case 7:
36
+ // rotateNeg90AndFlipImage
37
+ ctx.transform(0, -1, -1, 0, height, width);
38
+ break;
39
+ case 8:
40
+ // rotateNeg90
41
+ ctx.transform(0, -1, 1, 0, 0, width);
42
+ break;
43
+ default:
44
+ break;
45
+ }
46
+ }
47
+ ctx.drawImage(img, x, y, width, height);
48
+ }
@@ -1,144 +1,144 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- import {pick} from 'lodash';
6
-
7
- import {orient} from './orient';
8
- /* eslint-env browser */
9
-
10
- /**
11
- * Determins the dimensions of an image
12
- * @param {Object} constraints
13
- * @param {Number} constraints.width
14
- * @param {Number} constraints.height
15
- * @param {Number} maxWidth
16
- * @param {Number} maxHeight
17
- * @returns {Object}
18
- */
19
- function computeDimensions({width, height}, maxWidth, maxHeight) {
20
- if (height > width) {
21
- if (height > maxHeight) {
22
- width = (width * maxHeight) / height;
23
- height = maxHeight;
24
- }
25
-
26
- if (width > maxWidth) {
27
- height = (height * maxWidth) / width;
28
- width = maxWidth;
29
- }
30
- } else {
31
- if (width > maxWidth) {
32
- height = (height * maxWidth) / width;
33
- width = maxWidth;
34
- }
35
-
36
- if (height > maxHeight) {
37
- width = (width * maxHeight) / height;
38
- height = maxHeight;
39
- }
40
- }
41
-
42
- return {height, width};
43
- }
44
-
45
- /**
46
- * Measures an image file and produces a thumbnail for it
47
- * @param {Object} options
48
- * @param {Blob|ArrayBuffer} options.file
49
- * @param {Number} options.thumbnailMaxWidth
50
- * @param {Number} options.thumbnailMaxHeight
51
- * @param {Boolean} options.enableThumbnails
52
- * @param {Object} options.logger
53
- * @param {Boolean} options.isAvatar
54
- * @returns {Promise<Array>} Buffer, Dimensions, thumbnailDimensions
55
- */
56
- export default function processImage({
57
- file,
58
- type,
59
- thumbnailMaxWidth,
60
- thumbnailMaxHeight,
61
- enableThumbnails,
62
- logger,
63
- isAvatar,
64
- }) {
65
- if (!type || !type.startsWith('image')) {
66
- return Promise.resolve();
67
- }
68
-
69
- file = file instanceof Blob ? file : new Blob([file]);
70
-
71
- return new Promise((resolve, reject) => {
72
- const img = new Image();
73
-
74
- img.onload = function onload() {
75
- resolve(img);
76
- };
77
- img.onerror = reject;
78
- img.src = URL.createObjectURL(file);
79
- }).then((img) => {
80
- const fileDimensions = pick(img, 'height', 'width');
81
-
82
- if (isAvatar) {
83
- // only if image is a profile avatar
84
- logger.info('dimensions will be set for avatar image');
85
- const size =
86
- fileDimensions.height > fileDimensions.width ? fileDimensions.height : fileDimensions.width;
87
-
88
- fileDimensions.height = size;
89
- fileDimensions.width = size;
90
- }
91
- if (!enableThumbnails) {
92
- logger.info('thumbnails not enabled');
93
-
94
- return [null, fileDimensions, null];
95
- }
96
- const thumbnailDimensions = computeDimensions(
97
- fileDimensions,
98
- thumbnailMaxWidth,
99
- thumbnailMaxHeight
100
- );
101
-
102
- const canvas = document.createElement('canvas');
103
- const ctx = canvas.getContext('2d');
104
- const {width, height} = thumbnailDimensions;
105
-
106
- // explanation of orientation:
107
- // https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
108
- if (file.orientation && file.orientation > 4) {
109
- canvas.width = height;
110
- canvas.height = width;
111
- thumbnailDimensions.width = height;
112
- thumbnailDimensions.height = width;
113
- } else {
114
- canvas.width = thumbnailDimensions.width;
115
- canvas.height = thumbnailDimensions.height;
116
- }
117
-
118
- orient(
119
- {
120
- orientation: file && file.orientation ? file.orientation : '',
121
- img,
122
- x: 0,
123
- y: 0,
124
- width,
125
- height,
126
- ctx,
127
- },
128
- file
129
- );
130
-
131
- const parts = canvas.toDataURL('image/png').split(',');
132
- // Thumbnail uploads were failing with common/base64 decoding
133
- const byteString = atob(parts[1]);
134
-
135
- const buffer = new ArrayBuffer(byteString.length);
136
- const view = new DataView(buffer);
137
-
138
- for (let i = 0; i < byteString.length; i += 1) {
139
- view.setUint8(i, byteString.charCodeAt(i));
140
- }
141
-
142
- return [buffer, fileDimensions, thumbnailDimensions];
143
- });
144
- }
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import {pick} from 'lodash';
6
+
7
+ import {orient} from './orient';
8
+ /* eslint-env browser */
9
+
10
+ /**
11
+ * Determins the dimensions of an image
12
+ * @param {Object} constraints
13
+ * @param {Number} constraints.width
14
+ * @param {Number} constraints.height
15
+ * @param {Number} maxWidth
16
+ * @param {Number} maxHeight
17
+ * @returns {Object}
18
+ */
19
+ function computeDimensions({width, height}, maxWidth, maxHeight) {
20
+ if (height > width) {
21
+ if (height > maxHeight) {
22
+ width = (width * maxHeight) / height;
23
+ height = maxHeight;
24
+ }
25
+
26
+ if (width > maxWidth) {
27
+ height = (height * maxWidth) / width;
28
+ width = maxWidth;
29
+ }
30
+ } else {
31
+ if (width > maxWidth) {
32
+ height = (height * maxWidth) / width;
33
+ width = maxWidth;
34
+ }
35
+
36
+ if (height > maxHeight) {
37
+ width = (width * maxHeight) / height;
38
+ height = maxHeight;
39
+ }
40
+ }
41
+
42
+ return {height, width};
43
+ }
44
+
45
+ /**
46
+ * Measures an image file and produces a thumbnail for it
47
+ * @param {Object} options
48
+ * @param {Blob|ArrayBuffer} options.file
49
+ * @param {Number} options.thumbnailMaxWidth
50
+ * @param {Number} options.thumbnailMaxHeight
51
+ * @param {Boolean} options.enableThumbnails
52
+ * @param {Object} options.logger
53
+ * @param {Boolean} options.isAvatar
54
+ * @returns {Promise<Array>} Buffer, Dimensions, thumbnailDimensions
55
+ */
56
+ export default function processImage({
57
+ file,
58
+ type,
59
+ thumbnailMaxWidth,
60
+ thumbnailMaxHeight,
61
+ enableThumbnails,
62
+ logger,
63
+ isAvatar,
64
+ }) {
65
+ if (!type || !type.startsWith('image')) {
66
+ return Promise.resolve();
67
+ }
68
+
69
+ file = file instanceof Blob ? file : new Blob([file]);
70
+
71
+ return new Promise((resolve, reject) => {
72
+ const img = new Image();
73
+
74
+ img.onload = function onload() {
75
+ resolve(img);
76
+ };
77
+ img.onerror = reject;
78
+ img.src = URL.createObjectURL(file);
79
+ }).then((img) => {
80
+ const fileDimensions = pick(img, 'height', 'width');
81
+
82
+ if (isAvatar) {
83
+ // only if image is a profile avatar
84
+ logger.info('dimensions will be set for avatar image');
85
+ const size =
86
+ fileDimensions.height > fileDimensions.width ? fileDimensions.height : fileDimensions.width;
87
+
88
+ fileDimensions.height = size;
89
+ fileDimensions.width = size;
90
+ }
91
+ if (!enableThumbnails) {
92
+ logger.info('thumbnails not enabled');
93
+
94
+ return [null, fileDimensions, null];
95
+ }
96
+ const thumbnailDimensions = computeDimensions(
97
+ fileDimensions,
98
+ thumbnailMaxWidth,
99
+ thumbnailMaxHeight
100
+ );
101
+
102
+ const canvas = document.createElement('canvas');
103
+ const ctx = canvas.getContext('2d');
104
+ const {width, height} = thumbnailDimensions;
105
+
106
+ // explanation of orientation:
107
+ // https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
108
+ if (file.orientation && file.orientation > 4) {
109
+ canvas.width = height;
110
+ canvas.height = width;
111
+ thumbnailDimensions.width = height;
112
+ thumbnailDimensions.height = width;
113
+ } else {
114
+ canvas.width = thumbnailDimensions.width;
115
+ canvas.height = thumbnailDimensions.height;
116
+ }
117
+
118
+ orient(
119
+ {
120
+ orientation: file && file.orientation ? file.orientation : '',
121
+ img,
122
+ x: 0,
123
+ y: 0,
124
+ width,
125
+ height,
126
+ ctx,
127
+ },
128
+ file
129
+ );
130
+
131
+ const parts = canvas.toDataURL('image/png').split(',');
132
+ // Thumbnail uploads were failing with common/base64 decoding
133
+ const byteString = atob(parts[1]);
134
+
135
+ const buffer = new ArrayBuffer(byteString.length);
136
+ const view = new DataView(buffer);
137
+
138
+ for (let i = 0; i < byteString.length; i += 1) {
139
+ view.setUint8(i, byteString.charCodeAt(i));
140
+ }
141
+
142
+ return [buffer, fileDimensions, thumbnailDimensions];
143
+ });
144
+ }