如何在node.js中使用graphicsmagick裁剪圆形图片(其他使用任何其他方式在node.js上制作)
How to use graphicsmagick in node.js to crop circle picture (other use any other way to make this on node.js)
如何使用graphicsmagick麦田圈图片?
(使用png透明背景外圈)
我在 node.js
中使用 graphicsmagick,或者有任何其他方法在 node.js
?
我使用另一个模块来解决这个问题:
此代码用于方形图像 (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"));
});
我可以使用以下插件做到这一点:
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
})
经过几个小时的摆弄,我找到了一个使用 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');
});
});
我花了几个小时才弄明白
- 我想避免使用第三方软件,例如 ImageMagick(许多 npm 包都建立在它之上)
- node-pngjs 似乎只支持 PNG 文件 + 需要太多自定义代码
这是我使用 sharp 的解决方案:
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)
);
这是使用 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
使用裁剪
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);
});
});
});
});
}
如何使用graphicsmagick麦田圈图片?
(使用png透明背景外圈)
我在 node.js
中使用 graphicsmagick,或者有任何其他方法在 node.js
?
我使用另一个模块来解决这个问题:
此代码用于方形图像 (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"));
});
我可以使用以下插件做到这一点: 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
})
经过几个小时的摆弄,我找到了一个使用 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');
});
});
我花了几个小时才弄明白
- 我想避免使用第三方软件,例如 ImageMagick(许多 npm 包都建立在它之上)
- node-pngjs 似乎只支持 PNG 文件 + 需要太多自定义代码
这是我使用 sharp 的解决方案:
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)
);
这是使用 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
使用裁剪
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);
});
});
});
});
}