Files: b940897e2abe771c53af30e033cffd7191f4bd6f / blob / html / input.js
4828 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 | ev.target.value = '' |
63 | }) |
64 | } |
65 | reader.readAsArrayBuffer(file) |
66 | } |
67 | } |
68 | }) |
69 | }) |
70 | } |
71 | } |
72 | |
73 | function getImage (file, cb) { |
74 | var image = document.createElement('img') |
75 | image.onload = () => cb(image) |
76 | image.src = global.URL.createObjectURL(file) |
77 | image.style.display = 'block' |
78 | if (image.complete) cb(image) |
79 | } |
80 | |
81 | function resize (image, width, height) { |
82 | var imageHeight = image.height |
83 | var imageWidth = image.width |
84 | |
85 | var multiplier = (height / image.height) |
86 | if (multiplier * imageWidth < width) { |
87 | multiplier = width / image.width |
88 | } |
89 | |
90 | var finalWidth = imageWidth * multiplier |
91 | var finalHeight = imageHeight * multiplier |
92 | |
93 | var offsetX = (finalWidth - width) / 2 |
94 | var offsetY = (finalHeight - height) / 2 |
95 | |
96 | var canvas = document.createElement('canvas') |
97 | canvas.width = width |
98 | canvas.height = height |
99 | var ctx = canvas.getContext('2d') |
100 | ctx.drawImage(image, -offsetX, -offsetY, finalWidth, finalHeight) |
101 | return canvas |
102 | } |
103 | |
104 | function getOrientation (file, callback) { |
105 | var reader = new global.FileReader() |
106 | reader.onload = function (e) { |
107 | var view = new DataView(e.target.result) |
108 | if (view.getUint16(0, false) !== 0xFFD8) return callback(-2) |
109 | var length = view.byteLength |
110 | var offset = 2 |
111 | while (offset < length) { |
112 | var marker = view.getUint16(offset, false) |
113 | offset += 2 |
114 | if (marker === 0xFFE1) { |
115 | if (view.getUint32(offset += 2, false) !== 0x45786966) return callback(-1) |
116 | var little = view.getUint16(offset += 6, false) === 0x4949 |
117 | offset += view.getUint32(offset + 4, little) |
118 | var tags = view.getUint16(offset, little) |
119 | offset += 2 |
120 | for (var i = 0; i < tags; i++) { |
121 | if (view.getUint16(offset + (i * 12), little) === 0x0112) { |
122 | return callback(view.getUint16(offset + (i * 12) + 8, little)) |
123 | } |
124 | } |
125 | } else if ((marker & 0xFF00) !== 0xFF00) { |
126 | break |
127 | } else { |
128 | offset += view.getUint16(offset, false) |
129 | } |
130 | } |
131 | return callback(-1) |
132 | } |
133 | reader.readAsArrayBuffer(file) |
134 | } |
135 | |
136 | function rotate (img, orientation) { |
137 | var canvas = document.createElement('canvas') |
138 | var ctx = canvas.getContext('2d') |
139 | |
140 | if (orientation === 6 || orientation === 8) { |
141 | canvas.width = img.height |
142 | canvas.height = img.width |
143 | ctx.translate(img.height / 2, img.width / 2) |
144 | if (orientation === 6) { |
145 | ctx.rotate(0.5 * Math.PI) |
146 | } else { |
147 | ctx.rotate(1.5 * Math.PI) |
148 | } |
149 | } else if (orientation === 3) { |
150 | canvas.width = img.width |
151 | canvas.height = img.height |
152 | ctx.rotate(1 * Math.PI) |
153 | ctx.translate(img.width / 2, img.height / 2) |
154 | } else { |
155 | return img |
156 | } |
157 | |
158 | ctx.drawImage(img, -img.width / 2, -img.height / 2) |
159 | return canvas |
160 | } |
161 |
Built with git-ssb-web