源PNG图像将由PHP使用Imagick根据用户输入进行裁剪。结果是裁剪后的图像可能有也可能没有透明像素。我正在寻找一种方法来检测裁剪的图像是否具有透明度是或否,因此我可以将不透明的PNG转换为JPG。
这是我加载图片的代码:
// Get user input
$src = $_POST['src'];
$resize = json_decode($_POST['selection_data']);
// Load image (source image has transparency)
$dst = new Imagick($src);
// Crop image (the part that will be cropped is fully opaque)
$dst->cropImage($resize->selW, $resize->selH, $resize->selX, $resize->selY);
$dst->resizeImage($resize->dstW, $resize->dstH, imagick::FILTER_CATROM, 0.9, false);
在此之后,我可以使用$dst->getImageAlphaChannel()
检查Alpha通道。但是,无论裁剪的图像是否包含任何透明像素,都会返回true
,因为它是在加载源图像时设置的(具有透明度)。
检查透明像素的另一种方法是查看每个像素的alpha值小于1 *:
$alpha = false;
for ($x = 0; $x < $resize->dstW; $x++)
{
for ($y = 0; $y < $resize->dstH; $y++)
{
if ($dst->getImagePixelColor($x, $y)->getColorValue(Imagick::COLOR_ALPHA) < 1)
{
$alpha = true;
break 2;
}
}
}
但对于大图像(1000x1000),执行此操作需要30秒以上,这并不理想。
检测图像是否有透明像素的最快方法是什么?
*:在我正在测试的Debian Wheezy上,不透明像素实际上返回的alpha值为0.99999999976717(32位浮点数)。
答案 0 :(得分:1)
一种解决方案是:
创建一个新的图像,其背景颜色与您要测试的图像大小相同。
使用compositeImage
和COMPOSITE_ATOP
在新画布的顶部绘制图像。
获取所有颜色通道的图像统计信息。
对于任何完全没有任何透明度的图像,这两个图像应该具有完全相同的每个颜色通道的图像统计数据。
在代码中,这看起来像:
$imagick = new Imagick(realpath("../images/fnord.png"));
$newCanvas = new Imagick();
$newCanvas->newImage($imagick->getImageWidth(), $imagick->getImageHeight(), 'rgba(255, 255, 0, 1)', 'png');
$newCanvas->compositeimage($imagick, Imagick::COMPOSITE_ATOP, 0, 0);
function dumpInfo(Imagick $imagick) {
$identifyInfo = $imagick->getImageChannelStatistics();
foreach ($identifyInfo as $key => $value) {
echo "$key :";
if (is_array($value) == true) {
var_dump($value);
}
else {
echo $value;
}
echo "<br/>";
}
}
dumpInfo($imagick);
echo "<br/><br/>";
dumpInfo($newCanvas);
透明图像给出输出:
0:array(5){[&#34; mean&#34;] =&gt; float(0)[&#34; minima&#34;] =&gt;浮子(1.0E + 37) [&#34;最大值&#34;] =&GT; float(-1.0E-37)[&#34; standardDeviation&#34;] =&gt;浮动(0) [&#34;深度&#34;] =&GT; int(1)} 1:array(5){[&#34; mean&#34;] =&gt;浮动(5764.6123956044) [&#34;最小值&#34;] =&GT; float(0)[&#34; maxima&#34;] =&gt;浮动(53619) [&#34; standardDeviation&#34;] =&GT; float(11888.331707876)[&#34; depth&#34;] =&gt; int(15)} 2:array(5){[&#34; mean&#34;] =&gt; float(2058.7978021978)[&#34; minima&#34;] =&gt;浮动(0) [&#34;最大值&#34;] =&GT; float(34951)[&#34; standardDeviation&#34;] =&gt; float(5059.2862080476)[&#34; depth&#34;] =&gt; int(15)} 4:array(5){[&#34; mean&#34;] =&gt; float(6324.2305054945)[&#34; minima&#34;] =&gt; float(0)[&#34; maxima&#34;] =&gt;浮动(46773) [&#34; standardDeviation&#34;] =&GT; float(11356.366371237)[&#34; depth&#34;] =&gt; int(15)} 8:array(5){[&#34; mean&#34;] =&gt; float(46867.721934066)[&#34; minima&#34;] =&gt;浮动(0) [&#34;最大值&#34;] =&GT; float(65535)[&#34; standardDeviation&#34;] =&gt; float(26491.889090216)[&#34; depth&#34;] =&gt; int(15)} 32:array(5){ [&#34;平均&#34;] =&GT; float(0)[&#34; minima&#34;] =&gt; float(1.0E + 37)[&#34; maxima&#34;] =&gt; float(-1.0E-37)[&#34; standardDeviation&#34;] =&gt; float(0)[&#34; depth&#34;] =&gt; int(1)}
0:array(5){[&#34; mean&#34;] =&gt; float(0)[&#34; minima&#34;] =&gt;浮子(1.0E + 37) [&#34;最大值&#34;] =&GT; float(-1.0E-37)[&#34; standardDeviation&#34;] =&gt;浮动(0) [&#34;深度&#34;] =&GT; int(1)} 1:array(5){[&#34; mean&#34;] =&gt;浮动(51766.576175824) [&#34;最小值&#34;] =&GT; float(0)[&#34; maxima&#34;] =&gt;浮动(65535) [&#34; standardDeviation&#34;] =&GT; float(19889.498582657)[&#34; depth&#34;] =&gt; int(16)} 2:array(5){[&#34; mean&#34;] =&gt; float(48461.548131868)[&#34; minima&#34;] =&gt;浮动(0) [&#34;最大值&#34;] =&GT; float(65535)[&#34; standardDeviation&#34;] =&gt; float(24228.543381351)[&#34; depth&#34;] =&gt; int(16)} 4:array(5){[&#34; mean&#34;] =&gt; float(5353.375032967)[&#34; minima&#34;] =&gt; float(0)[&#34; maxima&#34;] =&gt;浮动(43081) [&#34; standardDeviation&#34;] =&GT; float(10139.362164338)[&#34; depth&#34;] =&gt; int(16)} 8:array(5){[&#34; mean&#34;] =&gt; float(0)[&#34; minima&#34;] =&gt; float(0)[&#34; maxima&#34;] =&gt; float(0)[&#34; standardDeviation&#34;] =&gt; float(0)[&#34; depth&#34;] =&gt; int(1)} 32 :array(5){[&#34; mean&#34;] =&gt; float(0)[&#34; minima&#34;] =&gt;浮子(1.0E + 37) [&#34;最大值&#34;] =&GT; float(-1.0E-37)[&#34; standardDeviation&#34;] =&gt;浮动(0) [&#34;深度&#34;] =&GT; int(1)}
如果不明显,那两个阵列绝对不一样。
1:array(5){[&#34; mean&#34;] =&gt;浮动(5764.6123956044) 1:array(5){[&#34; mean&#34;] =&gt;浮动(51766.576175824)
理论上你可以只检查getImageChannelStatistics
的实际值 - 如果你能弄清楚这些值实际意味着什么,但比较方法可能更安全。