Commit 766cfe96c4ca2476522a4214b7144b8a2e78b60d
Merge pull request #64 from ssbc/remove-exif
Add the ability to remove exif dataAnders Rune Jensen authored on 5/30/2018, 7:59:12 PM
GitHub committed on 5/30/2018, 7:59:12 PM
Parent: ba3a2674f63fa05229e42bfed91b68333405c1a9
Parent: 6165433879b4b23dc7e1435ca5bf81275ebb508f
Files changed
blob/html/input.js | changed |
package.json | changed |
blob/html/input.js | |||
---|---|---|---|
@@ -8,13 +8,13 @@ | |||
8 | 8 … | var Defer = require('pull-defer') | |
9 | 9 … | var BoxStream = require('pull-box-stream') | |
10 | 10 … | var crypto = require('crypto') | |
11 | 11 … | var zeros = Buffer.alloc(24, 0) | |
12 … | +var piexif = require('piexifjs') | ||
12 | 13 … | ||
13 | 14 … | module.exports = { | |
14 | 15 … | needs: nest({ | |
15 | 16 … | 'sbot.obs.connection': 'first' | |
16 | - | ||
17 | 17 … | }), | |
18 | 18 … | gives: nest('blob.html.input'), | |
19 | 19 … | create: function (api) { | |
20 | 20 … | return nest('blob.html.input', function FileInput (onAdded, opts = {}) { | |
@@ -27,12 +27,18 @@ | |||
27 | 27 … | ||
28 | 28 … | var mimeType = mime(file.name) | |
29 | 29 … | var fileName = file.name | |
30 | 30 … | ||
31 | - // handle exif orientation data and resize | ||
32 | - getOrientation(file, (orientation) => { | ||
31 … | + getFileData(file, function(fileData) { | ||
32 … | + var orientation = getOrientation(fileData) | ||
33 … | + | ||
34 … | + if ((typeof opts.removeExif == 'function' && opts.removeExif()) || | ||
35 … | + opts.removeExif === true) | ||
36 … | + fileData = removeExif(fileData, orientation) | ||
37 … | + | ||
38 … | + // handle exif orientation data and resize | ||
33 | 39 … | if (orientation >= 3 || opts.resize) { | |
34 | - getImage(file, (image) => { | ||
40 … | + getImage(fileData, (image) => { | ||
35 | 41 … | image = rotate(image, orientation) | |
36 | 42 … | if (opts.resize) { | |
37 | 43 … | image = resize(image, opts.resize.width, opts.resize.height) | |
38 | 44 … | } | |
@@ -43,17 +49,28 @@ | |||
43 | 49 … | image.toBlob(blob => { | |
44 | 50 … | next(blob) | |
45 | 51 … | }, mimeType, 0.85) | |
46 | 52 … | } else { | |
47 | - next(file) | ||
53 … | + next(dataURItoBlob(fileData)) | ||
48 | 54 … | } | |
49 | 55 … | }) | |
50 | 56 … | } else { | |
51 | 57 … | // don't process | |
52 | - next(file) | ||
58 … | + next(dataURItoBlob(fileData)) | ||
53 | 59 … | } | |
54 | 60 … | }) | |
55 | 61 … | ||
62 … | + function dataURItoBlob(dataURI) { | ||
63 … | + var byteString = atob(dataURI.split(',')[1]); | ||
64 … | + var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] | ||
65 … | + var ab = new ArrayBuffer(byteString.length); | ||
66 … | + var ia = new Uint8Array(ab); | ||
67 … | + for (var i = 0; i < byteString.length; i++) { | ||
68 … | + ia[i] = byteString.charCodeAt(i); | ||
69 … | + } | ||
70 … | + return new Blob([ab], {type: mimeString}); | ||
71 … | + } | ||
72 … | + | ||
56 | 73 … | function next (file) { | |
57 | 74 … | var reader = new global.FileReader() | |
58 | 75 … | reader.onload = function () { | |
59 | 76 … | var stream = pull.values(split(new Buffer(reader.result), 64 * 1024)) | |
@@ -82,9 +99,9 @@ | |||
82 | 99 … | ||
83 | 100 … | function getImage (file, cb) { | |
84 | 101 … | var image = document.createElement('img') | |
85 | 102 … | image.onload = () => cb(image) | |
86 | - image.src = global.URL.createObjectURL(file) | ||
103 … | + image.src = file | ||
87 | 104 … | image.style.display = 'block' | |
88 | 105 … | if (image.complete) cb(image) | |
89 | 106 … | } | |
90 | 107 … | ||
@@ -110,40 +127,34 @@ | |||
110 | 127 … | ctx.drawImage(image, -offsetX, -offsetY, finalWidth, finalHeight) | |
111 | 128 … | return canvas | |
112 | 129 … | } | |
113 | 130 … | ||
114 | -function getOrientation (file, callback) { | ||
131 … | +function getFileData(file, cb) | ||
132 … | +{ | ||
115 | 133 … | var reader = new global.FileReader() | |
116 | 134 … | reader.onload = function (e) { | |
117 | - var view = new DataView(e.target.result) | ||
118 | - if (view.getUint16(0, false) !== 0xFFD8) return callback(-2) | ||
119 | - var length = view.byteLength | ||
120 | - var offset = 2 | ||
121 | - while (offset < length) { | ||
122 | - var marker = view.getUint16(offset, false) | ||
123 | - offset += 2 | ||
124 | - if (marker === 0xFFE1) { | ||
125 | - if (view.getUint32(offset += 2, false) !== 0x45786966) return callback(-1) | ||
126 | - var little = view.getUint16(offset += 6, false) === 0x4949 | ||
127 | - offset += view.getUint32(offset + 4, little) | ||
128 | - var tags = view.getUint16(offset, little) | ||
129 | - offset += 2 | ||
130 | - for (var i = 0; i < tags; i++) { | ||
131 | - if (view.getUint16(offset + (i * 12), little) === 0x0112) { | ||
132 | - return callback(view.getUint16(offset + (i * 12) + 8, little)) | ||
133 | - } | ||
134 | - } | ||
135 | - } else if ((marker & 0xFF00) !== 0xFF00) { | ||
136 | - break | ||
137 | - } else { | ||
138 | - offset += view.getUint16(offset, false) | ||
139 | - } | ||
140 | - } | ||
141 | - return callback(-1) | ||
135 … | + cb(e.target.result) | ||
142 | 136 … | } | |
143 | - reader.readAsArrayBuffer(file) | ||
137 … | + reader.readAsDataURL(file) | ||
144 | 138 … | } | |
145 | 139 … | ||
140 … | +function removeExif (fileData, orientation) { | ||
141 … | + var clean = piexif.remove(fileData) | ||
142 … | + if (orientation != undefined) { // preserve | ||
143 … | + var exifData = { "0th": {} } | ||
144 … | + exifData["0th"][piexif.ImageIFD.Orientation] = orientation | ||
145 … | + var exifStr = piexif.dump(exifData) | ||
146 … | + return piexif.insert(exifStr, clean) | ||
147 … | + } | ||
148 … | + else | ||
149 … | + return clean | ||
150 … | +} | ||
151 … | + | ||
152 … | +function getOrientation (fileData) { | ||
153 … | + var exif = piexif.load(fileData); | ||
154 … | + return exif["0th"][piexif.ImageIFD.Orientation] | ||
155 … | +} | ||
156 … | + | ||
146 | 157 … | function rotate (img, orientation) { | |
147 | 158 … | var canvas = document.createElement('canvas') | |
148 | 159 … | var ctx = canvas.getContext('2d') | |
149 | 160 … |
package.json | ||
---|---|---|
@@ -42,8 +42,9 @@ | ||
42 | 42 … | "html-escape": "^2.0.0", |
43 | 43 … | "human-time": "0.0.1", |
44 | 44 … | "mutant": "^3.21.2", |
45 | 45 … | "mutant-pull-reduce": "^1.1.0", |
46 … | + "piexifjs": "^1.0.4", | |
46 | 47 … | "pull-abortable": "^4.1.0", |
47 | 48 … | "pull-box-stream": "~1.0.13", |
48 | 49 … | "pull-cat": "^1.1.11", |
49 | 50 … | "pull-defer": "~0.2.2", |
Built with git-ssb-web