Permalink
Browse files

Merge branch 'feature/autoOrient' of git://github.com/kainosnoema/gm …

…into integration

Resolved Conflicts:
	lib/command.js
	lib/getters.js
  • Loading branch information...
2 parents 42b67a6 + 14fcbb2 commit 7a19eace7c3bd4f43349400949cdb66043e71046 @aheckmann committed Jan 12, 2012
Showing with 115 additions and 3 deletions.
  1. +1 −0 .gitignore
  2. +2 −0 README.md
  3. BIN examples/imgs/originalSideways.jpg
  4. +41 −2 lib/command.js
  5. +1 −0 lib/convenience.js
  6. +52 −0 lib/convenience/autoOrient.js
  7. +5 −1 lib/getters.js
  8. +13 −0 test/autoOrient.js
View
@@ -3,6 +3,7 @@ examples/imgs/*
!examples/imgs/original.jpg
!examples/imgs/original.png
!examples/imgs/original.gif
+!examples/imgs/originalSideways.jpg
!examples/imgs/morpher.jpg
!examples/imgs/photo.JPG
*.swp
View
@@ -142,6 +142,7 @@ or clone the repo:
- getters
- [size](http://aheckmann.github.com/gm/#getters) - returns the size (WxH) of the image
+ - orientation - returns the EXIF orientation of the image
- [format](http://aheckmann.github.com/gm/#getters) - returns the image format (gif, jpeg, png, etc)
- [depth](http://aheckmann.github.com/gm/#getters) - returns the image color depth
- [color](http://aheckmann.github.com/gm/#getters) - returns the number of colors
@@ -151,6 +152,7 @@ or clone the repo:
- manipulation
- [antialias](http://aheckmann.github.com/gm/#antialias)
+ - autoOrient
- [bitdepth](http://aheckmann.github.com/gm/#bitdepth)
- [blur](http://aheckmann.github.com/gm/#blur)
- [charcoal](http://aheckmann.github.com/gm/#charcoal)
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -33,6 +33,9 @@ module.exports = function (proto) {
proto.in = args('_in');
proto.out = args('_out');
+ proto._preprocessor = [];
+ proto.preprocessor = args('_preprocessor');
+
/**
* Execute the command and write the image to the specified file name.
*
@@ -53,7 +56,12 @@ module.exports = function (proto) {
}
this.outname = name;
- return this._spawn(this.args(), true, callback);
+
+ var self = this;
+ this._preprocess(function (err) {
+ if (err) return callback(err);
+ self._spawn(self.args(), true, callback);
+ });
}
/**
@@ -75,7 +83,38 @@ module.exports = function (proto) {
this.outname = format + ":-";
}
- return this._spawn(this.args(), false, callback);
+ var self = this;
+ this._preprocess(function (err) {
+ if (err) return callback(err);
+ return self._spawn(self.args(), false, callback);
+ });
+ }
+
+ /**
+ * Run any preProcessor functions in series. Used by autoOrient.
+ *
+ * @param {Function} callback
+ * @return {Object} gm
+ */
+
+ proto._preprocess = function _preprocess (callback) {
+ if (!this._preprocessor.length) return callback();
+
+ // execute preprocessors in series
+ var self = this
+ , series = this._preprocessor.map(wrapSeries);
+
+ series.shift().call(this);
+
+ function wrapSeries (func) {
+ return function () {
+ func.call(self, function () {
+ var next = series.shift();
+ if (!next) return callback();
+ next.call(self);
+ });
+ };
+ };
}
/**
View
@@ -9,4 +9,5 @@ module.exports = function (proto) {
require("./convenience/thumb")(proto);
require("./convenience/morph")(proto);
require("./convenience/sepia")(proto);
+ require("./convenience/autoOrient")(proto);
}
@@ -0,0 +1,52 @@
+
+// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
+
+/**
+ * Extend proto.
+ */
+
+module.exports = function (proto) {
+
+ var exifTransforms = {
+ topleft: ''
+ , topright: ['-flip', 'horizontal']
+ , bottomright: ['-rotate', 180]
+ , bottomleft: ['-flip', 'vertical' ]
+ , lefttop: ['-transpose']
+ , righttop: ['-rotate', 90]
+ , rightbottom: ['-transverse']
+ , leftbottom: ['-rotate', 270]
+ }
+
+ proto.autoOrient = function autoOrient () {
+ var self = this;
+ self.preprocessor(function(callback) {
+ self.orientation({bufferStream: true}, function (err, orientation) {
+ if (err) return callback(err);
+
+ var transforms = exifTransforms[orientation.toLowerCase()];
+ if(transforms) {
+
+ // remove any existing transforms that might conflict
+ var index = self._out.indexOf(transforms[0]);
+ if (~index) {
+ self._out.splice(index, transforms.length);
+ }
+
+ // repage to fix coordinates and strip the EXIF
+ // profile since we can't reset Orientation=1
+ var adjustments = [];
+ adjustments.push('-page', '+0+0');
+ adjustments.push('+profile', '"*"');
+
+ self._out.unshift.apply(self._out, transforms.concat(adjustments));
+
+ }
+
+ callback(self);
+ });
+ });
+
+ return self;
+ }
+}
View
@@ -9,7 +9,7 @@ module.exports = function (gm) {
var proto = gm.prototype;
- ;['size', 'format', 'depth', 'color', 'res', 'filesize'].forEach(function (getter) {
+ ;['size', 'orientation', 'format', 'depth', 'color', 'res', 'filesize'].forEach(function (getter) {
proto[getter] = function (opts, callback) {
if (!callback) callback = opts, opts = {};
@@ -157,4 +157,8 @@ module.exports = function (gm) {
o.filesize = val;
};
+ helper.Orientation = function Orientation (o, val) {
+ o.orientation = val;
+ };
+
}
View
@@ -0,0 +1,13 @@
+
+// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)
+
+module.exports = function (_, dir, finish, gm) {
+
+ // this image is sideways, but may be auto-oriented by modern OS's
+ // try opening it in a browser to see its true orientation
+ gm(dir + '/originalSideways.jpg')
+ .autoOrient()
+ .write(dir + '/autoOrient.jpg', function autoOrient (err) {
+ finish(err);
+ });
+}

0 comments on commit 7a19eac

Please sign in to comment.