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