UNPKG

8.64 kBMarkdownView Raw
1![Version](https://img.shields.io/npm/v/jpeg-autorotate.svg)
2[![Build Status](https://travis-ci.org/johansatge/jpeg-autorotate.svg?branch=master)](https://travis-ci.org/johansatge/jpeg-autorotate)
3![Downloads](https://img.shields.io/npm/dm/jpeg-autorotate.svg)
4[![Install size](https://badgen.net/packagephobia/install/jpeg-autorotate)](https://packagephobia.com/result?p=jpeg-autorotate)
5![Last commit](https://badgen.net/github/last-commit/johansatge/jpeg-autorotate)
6
7![Icon](icon.png)
8
9> A node module to rotate JPEG images based on EXIF orientation.
10
11---
12
13* [What does it do](#what-does-it-do)
14* [Installation](#installation)
15* [Usage](#usage)
16 * [Options](#options)
17 * [CLI](#cli)
18 * [Node module](#node-module)
19 * [Sample usage](#sample-usage)
20 * [Error handling](#error-handling)
21* [Troubleshooting](#troubleshooting)
22 * [Thumbnail too large](#thumbnail-too-large)
23* [Changelog](#changelog)
24* [License](#license)
25* [Credits](#credits)
26
27## What does it do
28
29This module applies the right orientation to a JPEG image, based on its EXIF tag. More precisely, it:
30
31* Rotates the pixels
32* Rotates the thumbnail, if there is one
33* Writes `1` in the `Orientation` EXIF tag (this is the default orientation)
34* Updates the `PixelXDimension` and `PixelYDimension` EXIF values
35* Does **not** alter the other EXIF tags
36
37It may be useful, if:
38
39* You need to compress your image with a tool that strips EXIF data without rotating the pixels (like the great [ImageOptim](https://imageoptim.com/))
40* You need to upload the image, but the destination application does not support EXIF orientation (like [WordPress](https://wordpress.org/))
41* You just want to get rid of the orientation tag, while leaving the other tags **intact**
42
43> More information about EXIF:
44>
45> * [EXIF Orientation Handling Is a Ghetto](http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/)
46> * [Standard EXIF Tags](http://www.exiv2.org/tags.html)
47
48## Installation
49
50_This module needs Node `>=10`._
51
52Install with [npm](https://www.npmjs.com/):
53
54```bash
55$ npm install jpeg-autorotate --global
56# --global isn't required if you plan to use the node module
57```
58
59## Usage
60
61### Options
62
63| Option | Default value | Description |
64| --- | --- | --- |
65| `quality` | `100` | Quality of the JPEG. Uncompressed by default, so the resulting image may be bigger than the original one. |
66| `jpegjsMaxResolutionInMP` | `jpeg-js` default | `maxResolutionInMP` option in `jpeg-js` ([doc](https://github.com/eugeneware/jpeg-js#decode-options)) |
67| `jpegjsMaxMemoryUsageInMB` | `jpeg-js` default | `maxMemoryUsageInMB` option in `jpeg-js` ([doc](https://github.com/eugeneware/jpeg-js#decode-options)) |
68
69### CLI
70
71Rotate a single image:
72
73```bash
74$ jpeg-autorotate /Users/johan/IMG_1234.jpg
75```
76
77Rotate a set of images:
78
79```bash
80$ jpeg-autorotate /Users/johan/images/IMG_*.jpg
81```
82
83Glob support:
84
85```bash
86$ jpeg-autorotate "/Users/johan/images/IMG_*.{jpg,jpeg,JPG,JPEG}"
87```
88
89Passing options:
90
91```
92$ jpeg-autorotate /Users/johan/IMG_1234.jpg --quality=85 --jpegjsMaxResolutionInMP=1234
93```
94
95### Node module
96
97The Node module will load the image, apply the rotation, and return the binary data as a [Buffer](https://nodejs.org/api/buffer.html), allowing you to:
98
99* Save it on disk
100* Load it in an image processing module (like [jimp](https://github.com/oliver-moran/jimp), [lwip](https://github.com/EyalAr/lwip), [gm](https://github.com/aheckmann/gm)...)
101* ...
102
103#### Sample usage
104
105```js
106const jo = require('jpeg-autorotate')
107const options = {
108 quality: 8,
109 jpegjsMaxResolutionInMP: 1234,
110}
111const path = '/Users/johan/IMG_1234.jpg' // You can use a Buffer too
112
113//
114// With a callback:
115//
116jo.rotate(path, options, (error, buffer, orientation, dimensions, quality) => {
117 if (error) {
118 console.log('An error occurred when rotating the file: ' + error.message)
119 return
120 }
121 console.log(`Orientation was ${orientation}`)
122 console.log(`Dimensions after rotation: ${dimensions.width}x${dimensions.height}`)
123 console.log(`Quality: ${quality}`)
124 // ...Do whatever you need with the resulting buffer...
125})
126
127//
128// With a Promise:
129//
130jo.rotate(path, options)
131 .then(({buffer, orientation, dimensions, quality}) => {
132 console.log(`Orientation was ${orientation}`)
133 console.log(`Dimensions after rotation: ${dimensions.width}x${dimensions.height}`)
134 console.log(`Quality: ${quality}`)
135 // ...Do whatever you need with the resulting buffer...
136 })
137 .catch((error) => {
138 console.log('An error occurred when rotating the file: ' + error.message)
139 })
140```
141
142#### Error handling
143
144The `error` object returned by the module contains a readable `message`, but also a `code` for better error handling. Available codes are the following:
145
146```js
147const jo = require('jpeg-autorotate')
148
149jo.errors.read_file // File could not be opened
150jo.errors.read_exif // EXIF data could not be read
151jo.errors.no_orientation // No orientation tag was found
152jo.errors.unknown_orientation // The orientation tag is unknown
153jo.errors.correct_orientation // The image orientation is already correct
154jo.errors.rotate_file // An error occurred when rotating the image
155```
156
157Example:
158
159```js
160const jo = require('jpeg-autorotate')
161jo.rotate('/image.jpg')
162 .catch((error) => {
163 if (error.code === jo.errors.correct_orientation) {
164 console.log('The orientation of this image is already correct!')
165 }
166 })
167```
168
169## Troubleshooting
170
171### Thumbnail too large
172
173The [piexifjs](https://github.com/hMatoba/piexifjs/) module has a [64kb limit](https://github.com/hMatoba/piexifjs/blob/7b9140ab8ebb8ff620bb20f6319a337dd150092b/piexif.js#L236-L243) when reading thumbnails.
174If you get the _Given thumbnail is too large_ error, you can try to remove the thumbnail from the image before rotating it:
175
176```js
177import piexif from 'piexifjs'
178
179function deleteThumbnailFromExif(imageBuffer) {
180 const imageString = imageBuffer.toString('binary')
181 const exifObj = piexif.load(imageString)
182 delete exifObj['thumbnail']
183 delete exifObj['1st']
184 const exifBytes = piexif.dump(exifObj)
185 return Buffer.from(piexif.insert(exifBytes, imageString), 'binary')
186}
187```
188
189## Changelog
190
191This project uses [semver](http://semver.org/).
192
193| Version | Date | Notes |
194| --- | --- | --- |
195| `7.1.0` | 2020-10-10 | Introduce `jpegjsMaxResolutionInMP` & `jpegjsMaxMemoryUsageInMB` options (#26) |
196| `7.0.0` | 2020-09-19 | Don't publish test and linting files on NPM |
197| `6.0.0` | 2020-05-30 | Dependencies update<br>Drop support for Node < 10<br>From `jpeg-js` update: _images larger than 100 megapixels or requiring more than 512MB of memory to decode will throw_ |
198| `5.0.3` | 2019-12-24 | Fix multiple file support in CLI<br>Dependencies update |
199| `5.0.2` | 2019-09-28 | Dependencies update |
200| `5.0.1` | 2019-06-08 | Fix CLI support |
201| `5.0.0` | 2019-03-03 | Drop `--jobs` CLI option<br>Drop support for Node 6 & 7<br>Introduce new `quality` property in the `jo.rotate` callback<br>Public API now supports both callbacks and Promises<br>Update documentation accordingly<br>Update dependencies |
202| `4.0.1` | 2018-11-29 | Fix rotations `5` and `7` (issue #11) |
203| `4.0.0` | 2018-07-15 | Drop support for Node 4 & 5<br>Unpublish lockfile<br>Use prettier for code formatting<br>Update documentation<br>Update dependencies |
204| `3.1.0` | 2017-12-03 | Output dimensions after rotation |
205| `3.0.1` | 2017-07-30 | Node 8 support<br>Update dependencies |
206| `3.0.0` | 2017-02-11 | CLI supports `glob`<br>No more `node 0.12` support<br>Drop semicolons<br>Add eslint rules |
207| `2.0.0` | 2016-06-03 | Supports buffers in entry<br>Returns a buffer even if there was an error<br>Improves tests |
208| `1.1.0` | 2016-04-23 | Adds test suite, removes lwip dependency |
209| `1.0.3` | 2016-03-29 | Displays help when no path given in CLI |
210| `1.0.2` | 2016-03-21 | Adds missing options in CLI help |
211| `1.0.1` | 2016-03-21 | Fixes NPM publishing fail ^\_^ |
212| `1.0.0` | 2016-03-21 | Initial version |
213
214## License
215
216This project is released under the [MIT License](license.md).
217
218## Credits
219
220* [piexifjs](https://github.com/hMatoba/piexifjs)
221* [jpeg-js](https://github.com/eugeneware/jpeg-js)
222* [exif-orientation-examples](https://github.com/recurser/exif-orientation-examples)
223* [colors](https://github.com/Marak/colors.js)
224* [yargs](https://github.com/bcoe/yargs)
225* [FontAwesome](http://fontawesome.io/)
226* [Chai](http://chaijs.com/)
227* [Mocha](http://mochajs.org)
228* [eslint](http://eslint.org)
229* [glob](https://github.com/isaacs/node-glob)
230* [prettier](https://prettier.io/)
231* [fs-extra](https://github.com/jprichardson/node-fs-extra/)
232* [pixelmatch](https://github.com/mapbox/pixelmatch)
233* [pngjs](https://github.com/lukeapage/pngjs)