如何使用graphicsmagick crop circle picture?
(使用png透明背景外圈)
我在node.js
中使用了graphicsmagick,或者在node.js
中有任何其他方法可以做到这一点吗?
答案 0 :(得分:4)
经过几个小时的摆弄,我找到了一个使用node-gm和Imagemagick的干净解决方案。
var gm = require('gm').subClass({ imageMagick: true });
var original = 'app-server/photo.jpg';
var output = 'app-server/photo.png';
var size = 80;
gm(original)
.crop(233, 233,29,26)
.resize(size, size)
.write(output, function() {
gm(size, size, 'none')
.fill(output)
.drawCircle(size/2,size/2, size/2, 0)
.write(output, function(err) {
console.log(err || 'done');
});
});
答案 1 :(得分:1)
我使用另一个模块来解决这个问题:
此代码用于方形图像(this.height = this.width)
var fs = require('fs'),
PNG = require('pngjs').PNG;
fs.createReadStream(__dirname + "/input.png")
.pipe(new PNG({
filterType: 4
}))
.on('parsed', function() {
for (var y = 0; y < this.height; y++) {
for (var x = 0; x < this.width; x++) {
var idx = (this.width * y + x) << 2;
var radius = this.height / 2;
if(y >= Math.sqrt(Math.pow(radius, 2) - Math.pow(x - radius, 2)) + radius || y <= -(Math.sqrt(Math.pow(radius, 2) - Math.pow(x - radius, 2))) + radius) {
this.data[idx + 3] = 0;
}
}
}
this.pack().pipe(fs.createWriteStream(__dirname + "/output.png"));
});
答案 2 :(得分:1)
我能够使用以下插件执行此操作: https://www.npmjs.com/package/circle-image
安装后:
var images = require('circle-image');
var imageSizes = [125, 100, 30];
//uniqueId param is used to identify a user
//so user the primary key or something guaranteed to be unique
images.execute('imagepath', uniqueId, imageSizes).then(function (paths) {
//array of circularized image paths
console.log(paths[0]); //circle_user_{uniqueId}_150.png
})
答案 3 :(得分:0)
花我几个小时来弄清楚
这是我使用sharp的解决方案:
In [5]: j1 = ['8', '9']
In [6]: j1[0] + j1[1]
Out[6]: '89'
In [7]: 'f%d' % 2
Out[7]: 'f2'
In [8]: (j1[0] + j1[1]) % 2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-69ab5a8355ef> in <module>
----> 1 (j1[0] + j1[1]) % 2
TypeError: not all arguments converted during string formatting
In [9]: (int(j1[0]) + int(j1[1])) % 2
Out[9]: 1
如果您有兴趣,基于上面的代码,我创建了一个实用程序,该实用程序获取base64编码的图像(来自前端),并输出带有圆圈图像的文件流。使用temp-write软件包将处理过的图像保存在temp目录中。:
const sharp = require('sharp');
const width = 400,
r = width / 2,
circleShape = Buffer.from(`<svg><circle cx="${r}" cy="${r}" r="${r}" /></svg>`);
sharp('input.jpg')
.resize(width, width)
.composite([{
input: circleShape,
blend: 'dest-in'
}])
.webp()
.toFile('output.webp', (err, info) => err ?
console.error(err.message) :
console.log(info)
);
答案 4 :(得分:0)
以下是使用gm
和缓冲区的版本:
var gm = require('gm').subClass({ imageMagick: true });
var max = 200;
// buffer - is Buffer with picture
gm(buffer)
.autoOrient()
.gravity('Center')
.resize(max, max, '^')
.extent(max, max)
.noProfile()
.setFormat('png')
.out('(')
.rawSize(max, max)
.out('xc:Black')
.fill('White')
.drawCircle(max/2,max/2, max/2, 1)
.out('-alpha', 'Copy')
.out(')')
.compose('CopyOpacity')
.out('-composite')
.trim()
.toBuffer((err, buffer) => {
//...
});
上面的node.js代码等效于此ImageMagick命令,但是使用了缓冲区:
convert input.png \
-gravity Center \
-resize 200x200^ \
-extent 200x200 \
\( -size 200x200 \
xc:Black \
-fill White \
-draw 'circle 100 100 100 1' \
-alpha Copy \
\) -compose CopyOpacity -composite \
-trim output.png
答案 5 :(得分:0)
使用裁剪
const gm = require("gm");
const path = require("path");
const fs = require("fs");
const pathIn = path.resolve(__dirname, "images/in.jpeg");
function circularize(path, callback) {
const maskPath = path.replace(/\.[a-zA-Z]+$/g, "_mask.png");
const tmpPath = path.replace(/\.[a-zA-Z]+$/g, "_tmp.png");
gm(pathIn).size((err, iSize) => {
if (err) return callback(err, null);
const { width, height } = iSize;
const size = Math.min(width, height);
const r = size / 2;
gm(width, height, "transparent")
.fill("#ffffff")
.drawCircle(r, r, r, 1)
.setFormat("png")
.trim()
.write(maskPath, (err) => {
if (err) return callback(err, null);
gm(pathIn)
.gravity("Center")
.crop(size, size)
.write(tmpPath, (err) => {
if (err) return callback(err, null);
gm(tmpPath)
.composite(tmpPath, maskPath)
.compose("CopyOpacity")
.gravity("Center")
.setFormat("png")
.toBuffer((err, buffer) => {
if (err) return callback(err, null);
fs.unlinkSync(maskPath);
fs.unlinkSync(tmpPath);
return callback(null, buffer);
});
});
});
});
}