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