2011-03-31 4 views

답변

4

투명도를 한 눈에 감지 할 수있는 것처럼 보입니다.

The comments on the imagecolorat manual page 트루 컬러 이미지로 작업 할 때 결과 정수가 실제로 네 번 이동 될 수 있으며 네 번째는 알파 채널입니다 (다른 세 개는 빨강, 녹색 및 파랑 임). 따라서, $x$y에서 어떤 픽셀 위치를 주어, 당신은 사용 알파를 감지 할 수 있습니다 :

$rgba = imagecolorat($im,$x,$y); 
$alpha = ($rgba & 0x7F000000) >> 24; 
$red = ($rgba & 0xFF0000) >> 16; 
$green = ($rgba & 0x00FF00) >> 8; 
$blue = ($rgba & 0x0000FF); 

127 $alpha 분명히 완전히 투명하게하는, 제로가 완전히 불투명된다.

불행히도 픽셀 한 개를 개만 처리하면 이미지가 투명 해지고 트루 컬러 이미지에서만 작동합니다. 그렇지 않은 경우 imagecolorat은 색상 색인을 반환합니다.이 색인은 imagecolorsforindex을 사용하여 조회해야하며 실제로 알파 값이있는 배열을 반환합니다.

+0

GD가없는 다른 방법이 있습니까? –

+2

아마도이 특정 * 질문은 모두 GD에 관한 것입니다. 다른 (속는 사람) 질문을 고려하면 이미 GD를 사용하고 있기 때문에 문제가되지 않습니다. – Charles

+0

GD가없는 다른 방법이 있다면 모든 단일 픽셀을 확인할 필요가 없다는 것을 의미합니까? –

14

나는 이것이 오래된 것을 알고 있지만, 나는 PHP 문서의 주석에서 이것을 발견했다. 그 25 '의

PNG 이미지의 색 타입 바이트 오프셋 저장
<?php 
    function is_alpha_png($fn){ 
     return (ord(@file_get_contents($fn, NULL, NULL, 25, 1)) == 6); 
    } 
?> 

25. 가능한 값 (link)

여기

는 PNG 이미지를 알파 여부를 포함하는지 여부를 결정하는 함수 일 바이트이다

  • 0 - 스케일
  • 2 - RGB
  • 3 - RGB와 palett 전자
  • 4 - 그레이 스케일 + 알파
  • 6 - RGB + 알파

만하지만 PNG 이미지에 적용됩니다.

+2

이것은 작동하지 않습니다. 이 값은 특정 PNG *가 투명성을 지원함을 나타냅니다. 값이 나타내는 경우 실제로 투명 픽셀이 실제로 * 포함되어 있는지 확인해야합니다. – usr2564301

+1

@Jongware 당신은 절대적으로 옳습니다. 그러나 모든 이미지의 모든 픽셀을 검사하는 오버 헤드를 피할 수있는 좋은 방법이라고 생각합니다. 요구 사항에 따라 이미지에이 기능으로 투명성이 있는지 추측 할 수 없거나 추가로 처리해야할지 결정할 때 사용할 수 있습니다. –

+1

해결책은 먼저 'is_alpha_png' 함수로 검사하고 사실 인 경우 투명 픽셀을 상세하게 검색하는 것일 수 있습니다. –

2

이미지에 투명 픽셀이 있는지를 검사합니다. 그렇다면 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; 
} 
4

할 수 있습니다!

내가 빨리해야 하나의 함수에 모든 답변과 의견을 함께했습니다

& 신뢰성 :

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 
+0

이미지가 1x10000px 인 경우 어떻게해야합니까? 함수가 불필요하게 여전히 작은 이미지 크기를 조정합니다. 난 너비를 높이로 나누고 대신 비율을 확인하는 것이 좋습니다 .. 아니면 단순히 실제 파일 크기를 확인하십시오 .. 또한, 투명 픽셀을 말하면 10x10으로 이미지를 압축하여 찌그러 뜨릴 수도 있습니다. 좀 더 크게 만들고, 아마도 종횡비를 유지하는 것을 고려해야합니다. 그 외에는 잘 했어! +1 –

0

나는이 오래된 스레드 알지만, 내 의견으로는 거대한 통해 걷고 있기 때문에 개선이 필요 모든 픽셀을 검사하여 png가 투명하지 않다는 것을 확인하는 것은 시간 낭비입니다.그래서 일부 googleing 후 나는 Jon Fox's Blog을 발견하고 나는 더 빠르고 신뢰할 수있는 메모리 인쇄물에 최소 갖도록 W3C PNG Specification의 도움으로 자신의 코드를 개선 :

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); 
} 
0

cronoklee의 기능은 아주 좋은입니다하지만 사용되었을 때 버그를 발견했습니다. 8 비트 팔레트가있는 이미지에는 작동하지 않습니다. 다음은 고정 변형입니다.

public function hasAlpha($imgdata) 
{ 
    $w = imagesx($imgdata); 
    $h = imagesy($imgdata); 

    if($w>100 || $h>100){ //resize the image to save processing 
     $thumb = imagecreatetruecolor(100, 100); 
     imagealphablending($thumb, FALSE); 
     imagecopyresized($thumb, $imgdata, 0, 0, 0, 0, 100, 100, $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++) { 
      $ci = imagecolorat($imgdata, $i, $j); 
      $rgba = imagecolorsforindex($imgdata, $ci); 
      if($rgba['alpha']) { return true; } 
     } 
    } 
    return false; 
} 
관련 문제