1 | const jpegjs = require('jpeg-js')
|
2 |
|
3 | const m = {}
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | m.rotateBuffer = function(buffer, orientation, quality) {
|
10 | let jpeg = null
|
11 | try {
|
12 | jpeg = jpegjs.decode(buffer)
|
13 | } catch (error) {
|
14 | return Promise.reject(error)
|
15 | }
|
16 | let newBuffer = jpeg.data
|
17 |
|
18 | const transformations = {
|
19 | 2: {rotate: 0, flip: true},
|
20 | 3: {rotate: 180, flip: false},
|
21 | 4: {rotate: 180, flip: true},
|
22 | 5: {rotate: 90, flip: true},
|
23 | 6: {rotate: 90, flip: false},
|
24 | 7: {rotate: 270, flip: true},
|
25 | 8: {rotate: 270, flip: false},
|
26 | }
|
27 |
|
28 | if (transformations[orientation].rotate > 0) {
|
29 | newBuffer = rotatePixels(newBuffer, jpeg.width, jpeg.height, transformations[orientation].rotate)
|
30 | }
|
31 |
|
32 | const ratioWillChange = (transformations[orientation].rotate / 90) % 2 === 1
|
33 | const destWidth = ratioWillChange ? jpeg.height : jpeg.width
|
34 | const destHeight = ratioWillChange ? jpeg.width : jpeg.height
|
35 |
|
36 | if (transformations[orientation].flip) {
|
37 | newBuffer = flipPixels(newBuffer, destWidth, destHeight)
|
38 | }
|
39 |
|
40 | const newJpeg = jpegjs.encode({data: newBuffer, width: destWidth, height: destHeight}, quality)
|
41 | return Promise.resolve({buffer: newJpeg.data, width: destWidth, height: destHeight})
|
42 | }
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | function rotatePixels(buffer, width, height, degrees) {
|
49 | let loops = degrees / 90
|
50 | while (loops > 0) {
|
51 | const newBuffer = Buffer.alloc(buffer.length)
|
52 | let newOffset = 0
|
53 | for (let x = 0; x < width; x += 1) {
|
54 | for (let y = height - 1; y >= 0; y -= 1) {
|
55 | const offset = (width * y + x) << 2
|
56 | const pixel = buffer.readUInt32BE(offset, true)
|
57 | newBuffer.writeUInt32BE(pixel, newOffset, true)
|
58 | newOffset += 4
|
59 | }
|
60 | }
|
61 | buffer = newBuffer
|
62 | const newHeight = width
|
63 | width = height
|
64 | height = newHeight
|
65 | loops -= 1
|
66 | }
|
67 | return buffer
|
68 | }
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | function flipPixels(buffer, width, height) {
|
74 | const newBuffer = Buffer.alloc(buffer.length)
|
75 | for (let x = 0; x < width; x += 1) {
|
76 | for (let y = 0; y < height; y += 1) {
|
77 | const offset = (width * y + x) << 2
|
78 | const newOffset = (width * y + width - 1 - x) << 2
|
79 | const pixel = buffer.readUInt32BE(offset, true)
|
80 | newBuffer.writeUInt32BE(pixel, newOffset, true)
|
81 | }
|
82 | }
|
83 | return newBuffer
|
84 | }
|
85 |
|
86 | module.exports = m
|