2016-12-10 47 views
1

在最近的比賽中,我被賦予了從PNG圖像文件的alpha通道中提取二進制數據(另一個PNG)的任務。數據的編碼方式是,如果我從左上角的每個像素(例如80,78,71,13,10,26,10)讀取alpha通道中的值直到特定點,則生成的數據將形成另一個圖像。是否可以檢索0-255範圍內的PNG文件的像素的Alpha值?

最初我試圖用PHP完成這個任務,但是我碰到了一個我無法克服的障礙。考慮下面的代碼:

function pad($hex){ 
    return strlen($hex) < 2 ? "0$hex" : $hex; 
} 

$channel = ''; 

$image = 'image.png'; 
$ir = imagecreatefrompng($image); 
imagesavealpha($ir, true); 
list($width, $height) = getimagesize($image); 
for ($y = 0; $y < $height; $y++){ 
    for ($x = 0; $x < $width; $x++){ 
     $pixel = imagecolorat($ir, $x, $y); 
     $colors = imagecolorsforindex($ir, $pixel); 
     $a = pad(dechex($colors['alpha'])); 
     $channel.= $a; 
    } 
} 

運行在此之後,我注意到輸出不包含PNG神奇的數字,我只是不知道哪裏出了問題。經過一番挖掘,我發現$colors['alpha']只包含小於或等於127的值。由於數據已經在編碼0-255範圍內,所以我找不到解壓縮它的方法,最後(成功)改爲用node.js解決問題。

所以,我的問題是:是否有任何方式我能讀會中,而不是0-127,或者是這是一個硬一個0到255範圍內有返回值的PNG文件的alpha通道PHP和/或GD的編碼限制?

爲了記錄,我試圖使用($colors['alpha']/127)*255爲了嘗試僞造錯誤範圍內的值到正確的值,但無濟於事。

回答

2

這是GD的限制。根據https://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component,在GD源,它說:

GD具有隻有7 alpha通道的分辨率的位,和127是 透明的,不透明的0。一時的方便,一生的 兼容性。

$image = new Imagick(__DIR__ . DIRECTORY_SEPARATOR . 'image.png'); 
$x = 300; 
$y = 490; 
$pixel = $image->getImagePixelColor($x, $y); 
$colors = $pixel->getColor(true); 
echo 'Alpha value: ' . round($colors['a'] * 255, 0); 

ImageMagick的:

如果安裝ImageMagick的PHP擴展,你可以爲一個像素(讓我們用X = 300和Y = 490說吧)這樣得到0-255之間的alpha值: https://www.imagemagick.org

的ImageMagick的PHP(稱爲Imagick):http://php.net/manual/en/book.imagick.php

+0

這GD值得注意的是有趣@wizard因爲我在一塊的代碼中使用ImageColorAt並奇怪我爲什麼不得到確切的結果。稍後我會嘗試Imagemagick版本,看看我得到了什麼。當我寫它時,Imagick不可用,使用ImageColorAt比使用exec()的Imagemagick調用更容易。我想我應該更新我的代碼,因爲自從我編寫代碼以來,已經發生了很多變化! – Bonzo

+0

我實際上遍歷了錯誤的圖像,所以這個解決方案一開始並不起作用,但是修復了'for'循環之後,腳本正好返回了我所需要的。謝謝你的答案。 – SeinopSys

+0

嘗試關閉imagealphablending。 '$ img = imagecreatefrompng('image.png');' 'imagealphablending($ img,false);' 'imagesavealpha($ img,true); ' –

-1

在您的代碼:

list($width, $height) = getimagesize($image); 
  • 引用未在代碼中定義的變量'$ image'。
  • 使用getimagesize意味着$ image是一個文件名。
  • 所以這行從文件名獲得寬度和高度。

當我測試它時,這行打破了代碼。 你已經有了答案,但這是爲了後代。 考慮的代碼,我覺得:

$width=imagesx ($ir); 
$height=imagesy ($ir); 

會更合乎邏輯的(和實際工作)

+0

當我修剪這個問題的實際代碼時,這個問題留在了那裏,我現在修復了它。 – SeinopSys

相關問題