Imagemagick 进程永远挂在 Loopbackjs 上
Imagemagick processes hang forever on Loopbackjs
我得到这个代码来检查图像文件是否包含带有 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();
});
};
您使用的 -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
找到每个像素的最小值,以便有效满足所有三个条件:
- 蓝色超过绿色 20%
- 蓝色超过红色 20%
- 饱和度超过60%
-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 上,我的代码 运行s 在 30 秒内完成,而 -fx
等效代码需要将近 7 分钟。
我不知道 imagelagick 部分。但是对于节点部分,我看到你调用 next non regarding to imagemgick opertion。
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)
});
};
我得到这个代码来检查图像文件是否包含带有 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();
});
};
您使用的 -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
找到每个像素的最小值,以便有效满足所有三个条件:
- 蓝色超过绿色 20%
- 蓝色超过红色 20%
- 饱和度超过60%
-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 上,我的代码 运行s 在 30 秒内完成,而 -fx
等效代码需要将近 7 分钟。
我不知道 imagelagick 部分。但是对于节点部分,我看到你调用 next non regarding to imagemgick opertion。
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)
});
};