Merge pull request #291 from brandonaaron/corner-gravity

Add corner gravity support
This commit is contained in:
Lovell Fuller 2015-10-27 21:17:53 +00:00
commit 26fb75bf3f
3 changed files with 125 additions and 72 deletions

View File

@ -137,11 +137,11 @@ Sharp.prototype._write = function(chunk, encoding, callback) {
};
// Crop this part of the resized image (Center/Centre, North, East, South, West)
module.exports.gravity = {'center': 0, 'centre': 0, 'north': 1, 'east': 2, 'south': 3, 'west': 4};
module.exports.gravity = {'center': 0, 'centre': 0, 'north': 1, 'east': 2, 'south': 3, 'west': 4, 'northeast': 5, 'southeast': 6, 'southwest': 7, 'northwest': 8};
Sharp.prototype.crop = function(gravity) {
this.options.canvas = 'crop';
if (typeof gravity === 'number' && !Number.isNaN(gravity) && gravity >= 0 && gravity <= 4) {
if (typeof gravity === 'number' && !Number.isNaN(gravity) && gravity >= 0 && gravity <= 8) {
this.options.gravity = gravity;
} else if (typeof gravity === 'string' && typeof module.exports.gravity[gravity] === 'number') {
this.options.gravity = module.exports.gravity[gravity];

View File

@ -1096,6 +1096,16 @@ class PipelineWorker : public AsyncWorker {
case 4: // West
top = (inHeight - outHeight + 1) / 2;
break;
case 5: // Northeast
left = inWidth - outWidth;
break;
case 6: // Southeast
left = inWidth - outWidth;
top = inHeight - outHeight;
case 7: // Southwest
top = inHeight - outHeight;
case 8: // Northwest
break;
default: // Centre
left = (inWidth - outWidth + 1) / 2;
top = (inHeight - outHeight + 1) / 2;

View File

@ -9,76 +9,119 @@ sharp.cache(0);
describe('Crop gravities', function() {
it('North', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.north)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-north.jpg'), data, done);
});
});
var testSettings = [
{
name: 'North',
width: 320,
height: 80,
gravity: sharp.gravity.north,
fixture: 'gravity-north.jpg'
},
{
name: 'East',
width: 80,
height: 320,
gravity: sharp.gravity.east,
fixture: 'gravity-east.jpg'
},
{
name: 'South',
width: 320,
height: 80,
gravity: sharp.gravity.south,
fixture: 'gravity-south.jpg'
},
{
name: 'West',
width: 80,
height: 320,
gravity: sharp.gravity.west,
fixture: 'gravity-west.jpg'
},
{
name: 'Center',
width: 320,
height: 80,
gravity: sharp.gravity.center,
fixture: 'gravity-center.jpg'
},
{
name: 'Centre',
width: 80,
height: 320,
gravity: sharp.gravity.centre,
fixture: 'gravity-centre.jpg'
},
{
name: 'Northeast',
width: 320,
height: 80,
gravity: sharp.gravity.northeast,
fixture: 'gravity-north.jpg'
},
{
name: 'Northeast',
width: 80,
height: 320,
gravity: sharp.gravity.northeast,
fixture: 'gravity-east.jpg'
},
{
name: 'Southeast',
width: 320,
height: 80,
gravity: sharp.gravity.southeast,
fixture: 'gravity-south.jpg'
},
{
name: 'Southeast',
width: 80,
height: 320,
gravity: sharp.gravity.southeast,
fixture: 'gravity-east.jpg'
},
{
name: 'Southwest',
width: 320,
height: 80,
gravity: sharp.gravity.southwest,
fixture: 'gravity-south.jpg'
},
{
name: 'Southwest',
width: 80,
height: 320,
gravity: sharp.gravity.southwest,
fixture: 'gravity-west.jpg'
},
{
name: 'Northwest',
width: 320,
height: 80,
gravity: sharp.gravity.northwest,
fixture: 'gravity-north.jpg'
},
{
name: 'Northwest',
width: 80,
height: 320,
gravity: sharp.gravity.northwest,
fixture: 'gravity-west.jpg'
}
];
it('East', function(done) {
testSettings.forEach(function(settings) {
it(settings.name, function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.east)
.resize(settings.width, settings.height)
.crop(settings.gravity)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-east.jpg'), data, done);
assert.strictEqual(settings.width, info.width);
assert.strictEqual(settings.height, info.height);
fixtures.assertSimilar(fixtures.expected(settings.fixture), data, done);
});
});
it('South', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.south)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-south.jpg'), data, done);
});
});
it('West', function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.west)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-west.jpg'), data, done);
});
});
it('Center', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.center)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-center.jpg'), data, done);
});
});
it('Centre', function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.centre)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
fixtures.assertSimilar(fixtures.expected('gravity-centre.jpg'), data, done);
});
});
it('allows specifying the gravity as a string', function(done) {
@ -95,7 +138,7 @@ describe('Crop gravities', function() {
it('Invalid number', function() {
assert.throws(function() {
sharp(fixtures.inputJpg).crop(5);
sharp(fixtures.inputJpg).crop(9);
});
});