@@ -11,7 +11,12 @@ import i18n from 'browser/lib/i18n'
11
11
const STORAGE_FOLDER_PLACEHOLDER = ':storage'
12
12
const DESTINATION_FOLDER = 'attachments'
13
13
const PATH_SEPARATORS = escapeStringRegexp ( path . posix . sep ) + escapeStringRegexp ( path . win32 . sep )
14
-
14
+ /**
15
+ * @description
16
+ * Create a Image element to get the real size of image.
17
+ * @param {File } file the File object dropped.
18
+ * @returns {Promise<Image> } Image element created
19
+ */
15
20
function getImage ( file ) {
16
21
return new Promise ( ( resolve ) => {
17
22
const reader = new FileReader ( )
@@ -24,29 +29,54 @@ function getImage (file) {
24
29
} )
25
30
}
26
31
32
+ /**
33
+ * @description
34
+ * Get the orientation info from iamges's EXIF data.
35
+ * case 1: The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
36
+ * case 2: The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
37
+ * case 3: The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
38
+ * case 4: The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
39
+ * case 5: The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
40
+ * case 6: The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
41
+ * case 7: The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
42
+ * case 8: The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
43
+ * Other: reserved
44
+ * ref: http://sylvana.net/jpegcrop/exif_orientation.html
45
+ * @param {File } file the File object dropped.
46
+ * @returns {Promise<Number> } Orientation info
47
+ */
27
48
function getOrientation ( file ) {
28
49
const getData = arrayBuffer => {
29
50
const view = new DataView ( arrayBuffer )
51
+
52
+ // Not start with SOI(Start of image) Marker return fail value
30
53
if ( view . getUint16 ( 0 , false ) !== 0xFFD8 ) return - 2
31
54
const length = view . byteLength
32
55
let offset = 2
33
56
while ( offset < length ) {
34
57
const marker = view . getUint16 ( offset , false )
35
58
offset += 2
59
+ // Loop and seed for APP1 Marker
36
60
if ( marker === 0xFFE1 ) {
61
+ // return fail value if it isn't EXIF data
37
62
if ( view . getUint32 ( offset += 2 , false ) !== 0x45786966 ) {
38
63
return - 1
39
64
}
65
+ // Read TIFF header,
66
+ // First 2bytes defines byte align of TIFF data.
67
+ // If it is 0x4949="II", it means "Intel" type byte align.
68
+ // If it is 0x4d4d="MM", it means "Motorola" type byte align
40
69
const little = view . getUint16 ( offset += 6 , false ) === 0x4949
41
70
offset += view . getUint32 ( offset + 4 , little )
42
- const tags = view . getUint16 ( offset , little )
71
+ const tags = view . getUint16 ( offset , little ) // Get TAG number
43
72
offset += 2
44
73
for ( let i = 0 ; i < tags ; i ++ ) {
74
+ // Loop to find Orientation TAG and return the value
45
75
if ( view . getUint16 ( offset + ( i * 12 ) , little ) === 0x0112 ) {
46
76
return view . getUint16 ( offset + ( i * 12 ) + 8 , little )
47
77
}
48
78
}
49
- } else if ( ( marker & 0xFF00 ) !== 0xFF00 ) {
79
+ } else if ( ( marker & 0xFF00 ) !== 0xFF00 ) { // If not start with 0xFF, not a Marker
50
80
break
51
81
} else {
52
82
offset += view . getUint16 ( offset , false )
@@ -60,7 +90,13 @@ function getOrientation (file) {
60
90
reader . readAsArrayBuffer ( file . slice ( 0 , 64 * 1024 ) )
61
91
} )
62
92
}
63
-
93
+ /**
94
+ * @description
95
+ * Rotate image file to correct direction.
96
+ * Create a canvas and draw the image with correct direction, then export to base64 format.
97
+ * @param {* } file the File object dropped.
98
+ * @return {String } Base64 encoded image.
99
+ */
64
100
function fixRotate ( file ) {
65
101
return Promise . all ( [ getImage ( file ) , getOrientation ( file ) ] )
66
102
. then ( ( [ img , orientation ] ) => {
0 commit comments