Commit f147a2ac73f68764ed6b87c1a090b4418470d6e3
blob.html.input: auto orient images images based on exif data
Matt McKegg committed on 2/19/2017, 6:12:54 AMParent: f6852d8a65ff7eebb26e615d8b3da4bbb9f45cdd
Files changed
blob/html/input.js | changed |
blob/html/input.js | |||
---|---|---|---|
@@ -17,26 +17,47 @@ | |||
17 | 17 … | 'ev-change': function (ev) { | |
18 | 18 … | var file = ev.target.files[0] | |
19 | 19 … | if (!file) return | |
20 | 20 … | ||
21 | - if (opts.resize) { | ||
22 | - resize(file, opts.resize, next) | ||
23 | - } else { | ||
24 | - next(null, file) | ||
25 | - } | ||
21 … | + var mimeType = mime(file.name) | ||
22 … | + var fileName = file.name | ||
26 | 23 … | ||
27 | - function next (err, file) { | ||
28 | - if (err) return console.error(err) | ||
24 … | + // handle exif orientation data and resize | ||
25 … | + getOrientation(file, (orientation) => { | ||
26 … | + if (orientation >= 3 || opts.resize) { | ||
27 … | + getImage(file, (image) => { | ||
28 … | + image = rotate(image, orientation) | ||
29 … | + if (opts.resize) { | ||
30 … | + image = resize(image, opts.resize.width, opts.resize.height) | ||
31 … | + } | ||
32 … | + if (image.toBlob) { | ||
33 … | + if (mimeType !== 'image/jpeg' || mimeType !== 'image/png') { | ||
34 … | + mimeType = 'image/jpeg' | ||
35 … | + } | ||
36 … | + image.toBlob(blob => { | ||
37 … | + next(blob) | ||
38 … | + }, mimeType, 0.85) | ||
39 … | + } else { | ||
40 … | + next(file) | ||
41 … | + } | ||
42 … | + }) | ||
43 … | + } else { | ||
44 … | + // don't process | ||
45 … | + next(file) | ||
46 … | + } | ||
47 … | + }) | ||
48 … | + | ||
49 … | + function next (file) { | ||
29 | 50 … | var reader = new global.FileReader() | |
30 | 51 … | reader.onload = function () { | |
31 | 52 … | var stream = pull.values(split(new Buffer(reader.result), 64 * 1024)) | |
32 | 53 … | api.sbot.async.addBlob(stream, function (err, blob) { | |
33 | 54 … | if (err) return console.error(err) | |
34 | 55 … | onAdded({ | |
35 | 56 … | link: blob, | |
36 | - name: file.name, | ||
57 … | + name: fileName, | ||
37 | 58 … | size: reader.result.length || reader.result.byteLength, | |
38 | - type: mime(file.name) | ||
59 … | + type: mimeType | ||
39 | 60 … | }) | |
40 | 61 … | }) | |
41 | 62 … | } | |
42 | 63 … | reader.readAsArrayBuffer(file) | |
@@ -46,39 +67,92 @@ | |||
46 | 67 … | }) | |
47 | 68 … | } | |
48 | 69 … | } | |
49 | 70 … | ||
50 | -function resize (file, opts, cb) { | ||
71 … | +function getImage (file, cb) { | ||
51 | 72 … | var image = document.createElement('img') | |
52 | - | ||
53 | - image.onload = next | ||
73 … | + image.onload = () => cb(image) | ||
54 | 74 … | image.src = global.URL.createObjectURL(file) | |
55 | 75 … | image.style.display = 'block' | |
76 … | + if (image.complete) cb(image) | ||
77 … | +} | ||
56 | 78 … | ||
57 | - if (image.complete) next() | ||
79 … | +function resize (image, width, height) { | ||
80 … | + var imageHeight = image.height | ||
81 … | + var imageWidth = image.width | ||
58 | 82 … | ||
59 | - function next () { | ||
60 | - var imageHeight = image.height | ||
61 | - var imageWidth = image.width | ||
83 … | + var multiplier = (height / image.height) | ||
84 … | + if (multiplier * imageWidth < width) { | ||
85 … | + multiplier = width / image.width | ||
86 … | + } | ||
62 | 87 … | ||
63 | - var multiplier = (opts.height / image.height) | ||
64 | - if (multiplier * imageWidth < opts.width) { | ||
65 | - multiplier = opts.width / image.width | ||
66 | - } | ||
88 … | + var finalWidth = imageWidth * multiplier | ||
89 … | + var finalHeight = imageHeight * multiplier | ||
67 | 90 … | ||
68 | - var finalWidth = imageWidth * multiplier | ||
69 | - var finalHeight = imageHeight * multiplier | ||
91 … | + var offsetX = (finalWidth - width) / 2 | ||
92 … | + var offsetY = (finalHeight - height) / 2 | ||
70 | 93 … | ||
71 | - var offsetX = (finalWidth - opts.width) / 2 | ||
72 | - var offsetY = (finalHeight - opts.height) / 2 | ||
94 … | + var canvas = document.createElement('canvas') | ||
95 … | + canvas.width = width | ||
96 … | + canvas.height = height | ||
97 … | + var ctx = canvas.getContext('2d') | ||
98 … | + ctx.drawImage(image, -offsetX, -offsetY, finalWidth, finalHeight) | ||
99 … | + return canvas | ||
100 … | +} | ||
73 | 101 … | ||
74 | - var canvas = document.createElement('canvas') | ||
75 | - canvas.width = opts.width | ||
76 | - canvas.height = opts.height | ||
77 | - var ctx = canvas.getContext('2d') | ||
78 | - ctx.drawImage(image, -offsetX, -offsetY, finalWidth, finalHeight) | ||
79 | - canvas.toBlob(blob => { | ||
80 | - blob.name = file.name | ||
81 | - cb(null, blob) | ||
82 | - }, 'image/' + opts.type, 0.85) | ||
102 … | +function getOrientation (file, callback) { | ||
103 … | + var reader = new global.FileReader() | ||
104 … | + reader.onload = function (e) { | ||
105 … | + var view = new DataView(e.target.result) | ||
106 … | + if (view.getUint16(0, false) !== 0xFFD8) return callback(-2) | ||
107 … | + var length = view.byteLength | ||
108 … | + var offset = 2 | ||
109 … | + while (offset < length) { | ||
110 … | + var marker = view.getUint16(offset, false) | ||
111 … | + offset += 2 | ||
112 … | + if (marker === 0xFFE1) { | ||
113 … | + if (view.getUint32(offset += 2, false) !== 0x45786966) return callback(-1) | ||
114 … | + var little = view.getUint16(offset += 6, false) === 0x4949 | ||
115 … | + offset += view.getUint32(offset + 4, little) | ||
116 … | + var tags = view.getUint16(offset, little) | ||
117 … | + offset += 2 | ||
118 … | + for (var i = 0; i < tags; i++) { | ||
119 … | + if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
120 … | + return callback(view.getUint16(offset + (i * 12) + 8, little)) | ||
121 … | + } | ||
122 … | + } | ||
123 … | + } else if ((marker & 0xFF00) !== 0xFF00) { | ||
124 … | + break | ||
125 … | + } else { | ||
126 … | + offset += view.getUint16(offset, false) | ||
127 … | + } | ||
128 … | + } | ||
129 … | + return callback(-1) | ||
83 | 130 … | } | |
131 … | + reader.readAsArrayBuffer(file) | ||
84 | 132 … | } | |
133 … | + | ||
134 … | +function rotate (img, orientation) { | ||
135 … | + var canvas = document.createElement('canvas') | ||
136 … | + var ctx = canvas.getContext('2d') | ||
137 … | + | ||
138 … | + if (orientation === 6 || orientation === 8) { | ||
139 … | + canvas.width = img.height | ||
140 … | + canvas.height = img.width | ||
141 … | + ctx.translate(img.height / 2, img.width / 2) | ||
142 … | + if (orientation === 6) { | ||
143 … | + ctx.rotate(0.5 * Math.PI) | ||
144 … | + } else { | ||
145 … | + ctx.rotate(1.5 * Math.PI) | ||
146 … | + } | ||
147 … | + } else if (orientation === 3) { | ||
148 … | + canvas.width = img.width | ||
149 … | + canvas.height = img.height | ||
150 … | + ctx.rotate(1 * Math.PI) | ||
151 … | + ctx.translate(img.width / 2, img.height / 2) | ||
152 … | + } else { | ||
153 … | + return img | ||
154 … | + } | ||
155 … | + | ||
156 … | + ctx.drawImage(img, -img.width / 2, -img.height / 2) | ||
157 … | + return canvas | ||
158 … | +} |
Built with git-ssb-web