Как проверить, имеет ли изображение прозрачные пиксели с библиотекой GD php?
Не похоже, что вы можете сразу обнаружить прозрачность.
Комментарии на imagecolorat
руководства imagecolorat
предполагают, что итоговое целое число при работе с изображением с истинным цветом фактически может быть сдвинуто в четыре раза, а четвертый – альфа-канал (остальные три – красный, зеленый и синий). Поэтому, учитывая любое местоположение пикселя в $x
и $y
, вы можете обнаружить альфу, используя:
$rgba = imagecolorat($im,$x,$y); $alpha = ($rgba & 0x7F000000) >> 24; $red = ($rgba & 0xFF0000) >> 16; $green = ($rgba & 0x00FF00) >> 8; $blue = ($rgba & 0x0000FF);
$alpha
of 127, по-видимому, полностью прозрачна, а нуль полностью непрозрачна.
К сожалению, вам может потребоваться обработать каждый пиксель в изображении, чтобы найти прозрачный, а затем это работает только с изображениями с истинным цветом. В противном случае imagecolorat
возвращает индекс цвета, который вы должны искать с помощью imagecolorsforindex
, который фактически возвращает массив с альфа-значением.
Я знаю, что это устарело, но я просто нашел это в комментариях к документам PHP. ( ссылка )
Вот функция, которая определяет, содержит ли PNG-изображение альфа или нет:
<?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 – оттенки серого + альфа
- 6 – RGB + альфа
Тем не менее, работает только для изображений PNG.
Это можно сделать!
Я объединил все ответы и комментарии в одну функцию, которая должна быть быстрой и надежной:
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
Довольно прямая функция, он проверяет, есть ли какой-либо прозрачный пиксель в изображении, если он есть, он вернет true.
$im = imagecreatefrompng('./transparent.png'); if(check_transparent($im)) { echo 'DA'; } else { echo 'NU'; } function check_transparent($im) { $width = imagesx($im); // Get the width of the image $height = imagesy($im); // Get the height of the image // We run the image pixel by pixel and as soon as we find a transparent pixel we stop and return true. for($i = 0; $i < $width; $i++) { for($j = 0; $j < $height; $j++) { $rgba = imagecolorat($im, $i, $j); if(($rgba & 0x7F000000) >> 24) { return true; } } } // If we dont find any pixel the function will return false. return false; }
Я знаю, что это старая нить, но, на мой взгляд, она нуждается в улучшении, так как прохождение огромного png путем проверки всех пикселей только для того, чтобы выяснить, что это непрозрачно, это пустая трата времени. Поэтому после некоторых googleing я нашел блог 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); }
в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); }