我得到这段代码来检查一个图像文件是否包含蓝色像素,其中包含Imagemagick并对它们进行计数,然后保存结果。
它运行得很好,但似乎有许多Imagemagick进程永远挂在服务器上,使它变得非常慢。
有什么方法可以改进这段代码并避免这种麻烦吗?
module.exports = function (File) {
File.observe('after save', function countPixels(ctx, next) {
if (ctx.instance && !ctx.instance.blue_pixels) {
var exec = require('child_process').exec;
// Convert file to retrieve only blue pixels:
exec('convert ' + ctx.instance.path + ' -fx "u.b>(u.g+0.2)&&u.b>(u.r+0.2)&&saturation>0.6" -format "%[fx:mean*w*h]" info:',
function (error, stdout, stderr) {
if (error !== null) {
return next(error);
} else {
ctx.instance.blue_pixels = stdout;
File.upsert(ctx.instance);
}
});
}
next();
});
};发布于 2016-09-07 10:48:01
您使用的-fx操作符速度慢得出了名--特别是对于大型图像。我试着用更快的方法铸造同样的公式,这可能会对你有所帮助。所以,我做了一个样本图像:
convert xc:red xc:lime -append \( xc:blue xc:cyan -append \) +append -resize 256x256! input.png

然后把你的表情改写如下:
convert input.png \
\( -clone 0 -separate -delete 0 -evaluate-sequence subtract -threshold 20% -write BG.png \) \
\( -clone 0 -separate -delete 1 -evaluate-sequence subtract -threshold 20% -write BR.png \) \
\( -clone 0 -colorspace hsl -separate -delete 0,2 -threshold 60% -write S.png \) \
-delete 0 \
-evaluate-sequence min result.png注意,-write XYZ.png只是可以删除的调试语句。
基本上,我正在构建符合您标准的所有像素的掩码,并将其变为白色,并使所有不符合您的标准的像素变为黑色,并在最后运行-evaluate-sequence min以找到每个像素的最小值,以便有效地满足所有三个条件:
-separate -delete N将图像分割为RGB通道,然后删除其中一个结果通道,因此如果我-delete 1 (即绿色通道),则只剩下红色和蓝色。下面是中间的调试映像。第一种情况是蓝色超过红色20%:

那么蓝色超过绿色20%:

最后,饱和度超过60%:

结果是:

您需要将您的-format "%[fx:mean*w*h]" info:放在输出图像名称的末尾,以获得饱和蓝色像素的计数。
如果我执行你的命令:
convert input.png -fx "u.b>(u.g+0.2)&&u.b>(u.r+0.2)&&saturation>0.6" result.png

我的大脑今天不太好,所以请做一些检查--我可能有什么东西是背对着的!
作为基准,在10,000x10,000像素的PNG上,我的代码运行时间为30秒,而-fx等价物则需要将近7分钟。
发布于 2016-09-07 11:12:40
我不知道想象的部分。但是对于节点部分,我看到您调用next non关于imagemgick操作。
module.exports = function (File) {
File.observe('after save', function countPixels(ctx, next) {
if (ctx.instance && !ctx.instance.blue_pixels) {
var exec = require('child_process').exec;
// Convert file to retrieve only blue pixels:
exec('convert ' + ctx.instance.path + ' -fx "u.b>(u.g+0.2)&&u.b>(u.r+0.2)&&saturation>0.6" -format "%[fx:mean*w*h]" info:',
function (error, stdout, stderr) {
if (error !== null) {
return next(error);
} else {
ctx.instance.blue_pixels = stdout;
File.upsert(ctx.instance);
next();
}
});
}
else{next();}
//next(); //run next hook ASAP (before imagemagick returns back the result)
});
};https://stackoverflow.com/questions/39364750
复制相似问题