问题来源
在前端开发当中,经常有展示圆形图像的需求。在H5开发当中,使用border-radius属性就可以解决,安卓或者IOS,肯定也有相应办法。
如果想在后端裁剪出圆形图片,该怎么解决呢?
Solution
ImageMagic(未验证)
如果系统使用的是imagemagic,可以使用如下命令裁剪:
convert -size x200 xc:none -fill walter.jpg -draw "circle 100,100 100,1" circle_thumb.png
对于于nodejs gm,代码如下:
var gm = require('gm').subClass({ imageMagick: true });
var original = 'app-server/photo.jpg';
var output = 'app-server/photo.png';
var size = ;
gm(original)
.crop(, ,,)
.resize(size, size)
.write(output, function() {
gm(size, size, 'none')
.fill(output)
.drawCircle(size/,size/, size/, )
.write(output, function(err) {
console.log(err || 'done');
});
});
注意,该部分代码来源于stackoverflow。由于博主电脑上用的是GraphicsMagic,所以
上述命令未经验证。
node-pngjs
裁剪从原理上来说,就是让处于
圆外的像素变成透明,即将其alpha通道改成0。所以可以直接读取并操作图片像素。
var fs = require('fs'),
PNG = require('pngjs').PNG;
var input = 'test.png';
fs.createReadStream(input)
.pipe(new PNG({filterType: }))
.on('parsed', function() {
for (var y = ; y < this.height; y++) {
for (var x = ; x < this.width; x++) {
var idx = (this.width * y + x) << ;
if (Math.pow(x-radius,) + Math.pow(y-radius,) > Math.pow(radius,)) {
this.data[idx+] = ;
}
}
}
this.pack().pipe(fs.createWriteStream(input));
callback(null, param);
});
值得注意的是,
node-pngjs只支持png图片的读写,所以在裁剪之前需要先对图片进行格式转化。这个办法的优势在于,
不依赖于图形处理库,只靠js代码就可以搞定。
参考
How to use graphicsmagick in node.js to crop circle picture (other use any other way to make this on node.js)
node-pngjs
Crop or mask an image into a circle