Jav*_*rra 14
我知道这是旧的,但我刚刚在PHP文档的评论中找到了这个.(链接)
以下是确定PNG图像是否包含alpha的函数:
Run Code Online (Sandbox Code Playgroud)<?php function is_alpha_png($fn){ return (ord(@file_get_contents($fn, NULL, NULL, 25, 1)) == 6); } ?>PNG图像的颜色类型存储在字节偏移25处.该第25个字节的可能值为:
- 0 - 灰度
- 2 - RGB
- 3 - 带调色板的RGB
- 4 - 灰度+ alpha
- 6 - RGB + alpha
仅适用于PNG图像.
看起来您不能一目了然地检测透明度.
imagecolorat手册页上的注释表明,使用真彩色图像时得到的整数实际上可以总共移动四次,第四个是alpha通道(其他三个是红色,绿色和蓝色).因此,在任何给定的像素位置$x和$y,您可以使用检测阿尔法:
$rgba = imagecolorat($im,$x,$y);
$alpha = ($rgba & 0x7F000000) >> 24;
$red = ($rgba & 0xFF0000) >> 16;
$green = ($rgba & 0x00FF00) >> 8;
$blue = ($rgba & 0x0000FF);
Run Code Online (Sandbox Code Playgroud)
一个$alpha127显然是完全透明的,而零是完全不透明的.
不幸的是,您可能需要处理图像中的每个像素,只是为了找到一个透明的像素,然后这只适用于真彩色图像.否则imagecolorat返回一个颜色索引,然后你必须使用它imagecolorsforindex,它实际上返回一个带有alpha值的数组.
可以办到!
我将所有答案和评论合并到一个应该快速可靠的功能中:
function hasAlpha($imgdata) {
$w = imagesx($imgdata);
$h = imagesy($imgdata);
if($w>50 || $h>50){ //resize the image to save processing if larger than 50px:
$thumb = imagecreatetruecolor(10, 10);
imagealphablending($thumb, FALSE);
imagecopyresized( $thumb, $imgdata, 0, 0, 0, 0, 10, 10, $w, $h );
$imgdata = $thumb;
$w = imagesx($imgdata);
$h = imagesy($imgdata);
}
//run through pixels until transparent pixel is found:
for($i = 0; $i<$w; $i++) {
for($j = 0; $j < $h; $j++) {
$rgba = imagecolorat($imgdata, $i, $j);
if(($rgba & 0x7F000000) >> 24) return true;
}
}
return false;
}
//SAMPLE USE:
hasAlpha( imagecreatefrompng("myfile.png") ); //returns true if img has transparency
Run Code Online (Sandbox Code Playgroud)
我知道这是一个旧线程,但在我看来它需要改进,因为通过检查所有像素来浏览一个巨大的 png 只是发现它不透明是浪费时间。因此,经过一番谷歌搜索后,我找到了Jon Fox 的博客,并在W3C PNG 规范的帮助下改进了他的代码,使其更加可靠、快速且内存印记最少:
function IsTransparentPng($File){
//32-bit pngs
//4 checks for greyscale + alpha and RGB + alpha
if ((ord(file_get_contents($File, false, null, 25, 1)) & 4)>0){
return true;
}
//8 bit pngs
$fd=fopen($File, 'r');
$continue=true;
$plte=false;
$trns=false;
$idat=false;
while($continue===true){
$continue=false;
$line=fread($fd, 1024);
if ($plte===false){
$plte=(stripos($line, 'PLTE')!==false);
}
if ($trns===false){
$trns=(stripos($line, 'tRNS')!==false);
}
if ($idat===false){
$idat=(stripos($line, 'IDAT')!==false);
}
if ($idat===false and !($plte===true and $trns===true)){
$continue=true;
}
}
fclose($fd);
return ($plte===true and $trns===true);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12248 次 |
| 最近记录: |