Files: ab512c6473ad4ed1ba9143dc61c51545cf6ce781 / blob / html / input.js
4790 bytesRaw
1 | var h = require('mutant/h') |
2 | var pull = require('pull-stream') |
3 | var mime = require('simple-mime')('application/octect-stream') |
4 | var split = require('split-buffer') |
5 | var nest = require('depnest') |
6 | |
7 | module.exports = { |
8 | needs: nest({ |
9 | 'sbot.async.addBlob': 'first' |
10 | }), |
11 | gives: nest('blob.html.input'), |
12 | create: function (api) { |
13 | return nest('blob.html.input', function FileInput (onAdded, opts = {}) { |
14 | return h('input', { |
15 | accept: opts.accept, |
16 | type: 'file', |
17 | 'ev-change': function (ev) { |
18 | var file = ev.target.files[0] |
19 | if (!file) return |
20 | |
21 | var mimeType = mime(file.name) |
22 | var fileName = file.name |
23 | |
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) { |
50 | var reader = new global.FileReader() |
51 | reader.onload = function () { |
52 | var stream = pull.values(split(new Buffer(reader.result), 64 * 1024)) |
53 | api.sbot.async.addBlob(stream, function (err, blob) { |
54 | if (err) return console.error(err) |
55 | onAdded({ |
56 | link: blob, |
57 | name: fileName, |
58 | size: reader.result.length || reader.result.byteLength, |
59 | type: mimeType |
60 | }) |
61 | }) |
62 | } |
63 | reader.readAsArrayBuffer(file) |
64 | } |
65 | } |
66 | }) |
67 | }) |
68 | } |
69 | } |
70 | |
71 | function getImage (file, cb) { |
72 | var image = document.createElement('img') |
73 | image.onload = () => cb(image) |
74 | image.src = global.URL.createObjectURL(file) |
75 | image.style.display = 'block' |
76 | if (image.complete) cb(image) |
77 | } |
78 | |
79 | function resize (image, width, height) { |
80 | var imageHeight = image.height |
81 | var imageWidth = image.width |
82 | |
83 | var multiplier = (height / image.height) |
84 | if (multiplier * imageWidth < width) { |
85 | multiplier = width / image.width |
86 | } |
87 | |
88 | var finalWidth = imageWidth * multiplier |
89 | var finalHeight = imageHeight * multiplier |
90 | |
91 | var offsetX = (finalWidth - width) / 2 |
92 | var offsetY = (finalHeight - height) / 2 |
93 | |
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 | } |
101 | |
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) |
130 | } |
131 | reader.readAsArrayBuffer(file) |
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 | } |
159 |
Built with git-ssb-web