PHP Conference Japan 2024

imagecolorat

(PHP 4, PHP 5, PHP 7, PHP 8)

imagecolorat取得像素顏色的索引

描述

imagecolorat(GdImage $image, int $x, int $y): int|false

傳回由 image 指定的影像中,位於指定位置的像素顏色索引。

如果影像為真色彩影像,此函式會將該像素的 RGB 值以整數傳回。 使用位元移位和遮罩來存取個別的紅色、綠色和藍色元件值

參數

image

一個 GdImage 物件,由影像建立函式之一傳回,例如 imagecreatetruecolor()

x

點的 x 座標。

y

點的 y 座標。

傳回值

傳回顏色索引,失敗則傳回 false

警告

此函式可能傳回布林值 false,但也可能傳回非布林值,但其計算結果為 false。 請閱讀關於 布林值 的章節以取得更多資訊。 使用 === 運算子來測試此函式的傳回值。

變更記錄

版本 描述
8.0.0 image 現在需要一個 GdImage 實例;先前,需要一個有效的 gd 資源

範例

範例 #1 存取不同的 RGB 值

<?php
$im
= imagecreatefrompng("php.png");
$rgb = imagecolorat($im, 10, 15);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

var_dump($r, $g, $b);
?>

上面的範例會輸出類似以下的內容

int(119)
int(123)
int(180)

範例 #2 使用 imagecolorsforindex() 取得人類可讀的 RGB 值

<?php
$im
= imagecreatefrompng("php.png");
$rgb = imagecolorat($im, 10, 15);

$colors = imagecolorsforindex($im, $rgb);

var_dump($colors);
?>

上面的範例會輸出類似以下的內容

array(4) {
  ["red"]=>
  int(119)
  ["green"]=>
  int(123)
  ["blue"]=>
  int(180)
  ["alpha"]=>
  int(127)
}

另請參閱

新增筆記

使用者貢獻的筆記 22 則筆記

15
Luciano Ropero
18 年前
我寫了一個函式,可計算給定影像資源的平均顏色,並以 "#rrggbb" 格式 (十六進位) 傳回

function average($img) {
$w = imagesx($img);
$h = imagesy($img);
$r = $g = $b = 0;
for($y = 0; $y < $h; $y++) {
for($x = 0; $x < $w; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r += $rgb >> 16;
$g += $rgb >> 8 & 255;
$b += $rgb & 255;
}
}
$pxls = $w * $h;
$r = dechex(round($r / $pxls));
$g = dechex(round($g / $pxls));
$b = dechex(round($b / $pxls));
if(strlen($r) < 2) {
$r = 0 . $r;
}
if(strlen($g) < 2) {
$g = 0 . $g;
}
if(strlen($b) < 2) {
$b = 0 . $b;
}
return "#" . $r . $g . $b;
}

不過,我注意到,您也可以使用 imagecopyresampled 產生 1px x 1px 的副本來獲得相當不錯的平均顏色 (產生的像素會使用平均顏色著色)。
8
alan hogan dot com slash contact
17 年前
正如 creamdog 先前指出的,此函式可取得 Alpha 通道! (手冊應該更新以包含此內容!)

$rgba = imagecolorat($im,$x,$y);
$alpha = ($rgba & 0x7F000000) >> 24;

$alpha 將包含透明度 (而非不透明度) 層級。 因此,最大值 127 將完全透明,而 0 將完全不透明。

使用此資訊,可以編寫類似於下方完全正常運作的簡單函式,以進行抖動 png 轉 gif 的轉換

<?php
$im
= imagecreatefrompng($pngRel);
$transparentColor = imagecolorallocate($im, 0xfe, 0x3, 0xf4 );
$height = imagesy($im);
$width = imagesx($im);
for(
$x = 0; $x < $width; $x++){
for(
$y = 0; $y < $height; $y++) {
$alpha = (imagecolorat($im,$x,$y) & 0x7F000000) >> 24;
//DITHER!
if ($alpha > 3 && (
$alpha >=127-3 ||
(
rand(0,127))>=(127-$alpha)
)){
imagesetpixel($im,$x,$y,$transparentColor);
}

}
}
imagecolortransparent($im, $transparentColor);
imagegif($im, $gifRel);//save
header("Content-type: image/gif");
readfile($gifRel); //pass thru to browser

?>
5
mumig at poczta dot onet dot pl
20 年前
imagecolorat() 對於真彩色 PNG 和索引式 PNG 的運作方式不同 - 對於真彩色,它會傳回顏色的值,對於索引式 PNG,它會傳回索引號碼,您必須使用 imagecolorsforindex() 來取得 RGB 顏色值。
7
justin at hoogs dot com dot au
12 年前
trimImage ( resource $image , int $colour , int $tolerance )

trimImage() 將會回傳圖片中所需像素的最頂端、最右端、最底端和最左端的位置 (即,尋找最小的圖片區域,以便您可以從圖片的外邊緣修剪給定的顏色)。

參數

image
圖片資源,由圖片建立函式之一回傳,例如 imagecreatetruecolor()。

colour
要「修剪」的顏色。允許範圍為 0(黑色)到 255(白色)。如果為 null(或超出 0 - 255 範圍),則會使用左上角顏色作為預設值。

tolerance
與顏色的可接受誤差範圍。0 (僅修剪完全相同的顏色) 到 255 (修剪所有顏色)。

傳回值
傳回一個陣列,包含超出顏色容差範圍的最外層像素。
array( int $top, int $right, int $bottom, int $left )

範例(以及實際函式)
<?php
function trimImage($im,$c,$t) {
// 如果修剪顏色 ($c) 不是介於 0 - 255 之間的數字
if (!is_numeric($c) || $c < 0 || $c > 255) {
// 從左上角抓取顏色並將其用作預設值
$rgb = imagecolorat($im, 2, 2); // 往內 2 個像素以避免邊緣雜訊
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$c = round(($r+$g+$b)/3); // rgb 的平均值對於預設值來說已足夠
}
// 如果容差 ($t) 不是介於 0 - 255 之間的數字,則使用 10 作為預設值
if (!is_numeric($t) || $t < 0 || $t > 255) $t = 10;

$w = imagesx($im); // 圖片寬度
$h = imagesy($im); // 圖片高度
for($x = 0; $x < $w; $x++) {
for(
$y = 0; $y < $h; $y++) {
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if (
(
$r < $c-$t || $r > $c+$t) && // 紅色不在修剪顏色的容差範圍內
($g < $c-$t || $g > $c+$t) && // 綠色不在修剪顏色的容差範圍內
($b < $c-$t || $b > $c+$t) // 藍色不在修剪顏色的容差範圍內
) {
// 使用 x 和 y 作為鍵,將所有行和所有列壓縮
// 成只有一個 X 陣列和一個 Y 陣列。
// 然而,鍵被視為字面值,因此它們不是按數字順序排列的,所以我們需要
// 對它們進行排序,以取得第一個和最後一個出現的 X 和 Y 的所需像素。
// 普通排序會移除鍵,因此我們也使用 x 和 y 作為值,
// 這樣它們仍然可用,而無需保留鍵。
$y_axis[$y] = $y;
$x_axis[$x] = $x;
// 注意:$y_axis[] = $y; 和 $x_axis[] = $x; 效果也一樣好
// 但會產生比必要大得多的陣列
// array_unique 會再次縮減大小,但此方法更快
}
}
}
// 對它們進行排序,以便第一次和最後一次出現都在開頭和結尾
sort($y_axis);
sort($x_axis);

$top = array_shift($y_axis); // Y 軸上第一個想要的像素
$right = array_pop($x_axis); // X 軸上最後一個想要的像素
$bottom = array_pop($y_axis); // Y 軸上最後一個想要的像素
$left = array_shift($x_axis); // X 軸上第一個想要的像素

return array($top,$right,$bottom,$left);
}

$image='test.jpg';
$im = imagecreatefromjpeg($image); // 我們需要資源

$c = (isset($_GET[c])) ? $_GET[c] : null; // 透過 GET 設定修剪顏色
$t = (isset($_GET[t])) ? $_GET[t] : null; // 透過 GET 設定容差

list($t,$r,$b,$l) = trimImage($im,$c,$t); // 找出上、右、下和左

$w = $r-$l; // 找出寬度
$h = $b-$t; // 找出高度

imagedestroy($im); // 釋放資源

// 以下僅用於視覺測試函式 ---------------------------------

$html_display = <<<HTM

<style type="text/css">
#stage {
position: relative;
float: left; // 使其與包含的圖片大小相同
}
#canvas {
border: solid 1px #FC3;
width:
{$w}px;
height:
{$h}px;
position: absolute;
top:
{$t}px;
left:
{$l}px;
}
img { border: solid 1px #EEE; }
</style>

HTM;

?>
<html>
<head>
<?=$html_display?>
</head>

<body>
<div id="stage">
<div id="canvas"></div>
<img src="test.jpg" />
</div>

</body>
</html>
1
Ray.Paseur 有時使用 Gmail
7 年前
imageColorAt() 對於超出範圍的像素座標發出 Notice 並傳回 FALSE。
3
justin at hoogs dot com dot au
11 年前
這改進了我先前的函式(它實際上只在少數灰階顏色上起作用)。顏色現在應該是十六進位顏色值。顏色和容差現在是選用參數。

trimImage ( resource $image [, str $colour [, int $tolerance]] )

trimImage() 將會回傳圖片中所需像素的最頂端、最右端、最底端和最左端的位置 (即,尋找最小的圖片區域,以便您可以從圖片的外邊緣修剪給定的顏色)。

參數

image
圖片資源,由圖片建立函式之一回傳,例如 imagecreatetruecolor()。

colour
要「修剪」的顏色的十六進位值。如果省略,則將使用左上角的顏色作為預設值。

tolerance
可接受的範圍與顏色的 +- 值。允許的範圍為 0 到 255。如果省略,則將使用 10 作為預設值。

傳回值
傳回超出顏色容差範圍的最外層像素的陣列。
array( int $top, int $right, int $bottom, int $left )

function trimImage($im,$c=null,$t=10) {
// 如果十六進位顏色 ($c) 存在,則嘗試轉換為十進位
if ($c) $rgb = @hexdec($c);
// 如果 hexdec 無法取得介於黑色 (0) 和白色 (16777215) 之間的值
// 從左上角抓取顏色(往內 2 個像素以避免邊緣雜訊)
if (!is_numeric($rgb) || $rgb < 0 || $rgb > 16777215) $rgb = imagecolorat($im, 2, 2);
// 將 $rgb 分割為紅色、綠色和藍色
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
// 確保容差 ($t) 是介於 0 - 255 之間的數字
if (!is_numeric($t) || $t < 0) $t = 0;
elseif ($t > 255) $t = 255;

$w = imagesx($im); $h = imagesy($im); // 圖片寬度和高度
for($x = 0; $x < $w; $x++) {
for($y = 0; $y < $h; $y++) {
$rgb = imagecolorat($im, $x, $y);
$red = ($rgb >> 16) & 0xFF;
$grn = ($rgb >> 8) & 0xFF;
$blu = $rgb & 0xFF;
if (
$red < $r-$t || $red > $r+$t || // 不修剪紅色(也不在容差範圍內)
$grn < $g-$t || $grn > $g+$t || // 不修剪綠色(也不在容差範圍內)
$blu < $b-$t || $blu > $b+$t // 不修剪藍色(也不在容差範圍內)
) {
$y_axis[$y] = $y; $x_axis[$x] = $x; // 儲存想要的像素坐標
}
}
}
if (!$y_axis) $y_axis = $x_axis = array(0); // 避免修剪所有像素時發生錯誤
// 排序使第一個和最後一個出現的位置在開始和結束
sort($y_axis); sort($x_axis);

$t = array_shift($y_axis); // Y 軸上第一個想要的像素(頂部)
$r = array_pop($x_axis); // X 軸上最後一個想要的像素(右側)
$b = array_pop($y_axis); // Y 軸上最後一個想要的像素(底部)
$l = array_shift($x_axis); // X 軸上第一個想要的像素(左側)

return array($t,$r,$b,$l);
}
1
dewi at dewimorgan dot com
10 年前
要測試是否將此函數的回傳值處理為 RGB 或調色盤索引,請參閱 imageistruecolor(),或(對於 GD < 2.0.1 或 PHP 4 < 4.3.2)imagecolorstotal() == 0。

這裡似乎有很多註解需要多行才能將 RGB 或 RGBA 值轉換為十六進位字串 #AARRGGBB。在大多數情況下,這只需一行程式碼

$hex = sprintf("#%08X", imagecolorat($im32, $x, $y));
$hex = sprintf("#%08X", $rgb);
$hex = sprintf("#%08X", $argb);
$hex = sprintf("#%02X%06X", $rgba >> 24, $rgba & 0xFF000000);
$hex = sprintf("#00%02X%02X%02X", $r, $g, $b);
$hex = sprintf("#%02X%02X%02X%02X", $a, $r, $g, $b);

對於調色盤影像,則需要兩行
$cols = imagecolorsforindex($imPal, imagecolorat($imPal, $x, $y));
$hex = sprintf("#%08X", $cols['alpha'], $cols['red'], $cols['green'], $cols['blue']);
1
chandrachur at elegantsystems dot net
13 年前
這是一個有趣的程式碼,用於將白色背景的影像設為透明。它適用於任何背景,但您需要相應地調整顏色值。最適用於純雙色影像。我搜尋這類型的程式碼很久都找不到...看看是否能幫助到其他人。

<?php

function transparentImage($src){ //將白色背景的影像設為透明
$r1=80;
$g1=80;
$b1=80;
for(
$x = 0; $x < imagesx($src); ++$x)
{
for(
$y = 0; $y < imagesy($src); ++$y)
{
$color=imagecolorat($src, $x, $y);
$r = ($color >> 16) & 0xFF;
$g = ($color >> 8) & 0xFF;
$b = $color & 0xFF;
for(
$i=0;$i<270;$i++){
if(
$r.$g.$b==($r1+$i).($g1+$i).($b1+$i)){
$trans_colour = imagecolorallocatealpha($src, 0, 0, 0, 127);
imagefill($src, $x, $y, $trans_colour);
}
}
}
}

return
$src;
}

$image='abc/abc.jpg';
$src = imagecreatefromjpeg($image);
$src=transparentImage($src); //將 JPEG 設為透明

?>
1
T. Dekker
19 年前
在 GD 2.x 中,支援具有 alpha 通道的真色彩影像。GD 2.x 具有 7 位元 (0-127) 的 alpha 通道。

雖然大多數人習慣使用 8 位元 (0-255) 的 alpha 通道,但實際上 GD 的 7 位元 (0-127) 很方便。每個像素由一個 32 位元的有號整數表示,四個 8 位元的位元組排列如下

高位元組 <--> 低位元組
{Alpha 通道} {紅色} {綠色} {藍色}

對於有號整數,最左邊的位元或最高位元用於指示該值是否為負數,因此只留下 31 位元的實際資訊。PHP 的預設整數值是有號長整數,我們可以將單個 GD 調色盤項目儲存在其中。該整數為正數或負數會告訴我們是否為該調色盤項目啟用反鋸齒。
1
Super Moi
19 年前
這是用於更改色調的貢獻。

function colorize($path_image, $red, $green, $blue)
{
$im = imagecreatefrompng($path_image);
$pixel = array();

$n_im = imagecreatetruecolor(imagesx($im),imagesy($im));
$fond = imagecolorallocatealpha($n_im, 255, 255, 255, 0);
imagefill($n_im, 0, 0, $fond);

for($y=0;$y<imagesy($n_im);$y++)
{
for($x=0;$x<imagesx($n_im);$x++)
{
$rgb = imagecolorat($im, $x, $y);
$pixel = imagecolorsforindex($im, $rgb);

$r = min(round($red*$pixel['red']/169),255);
$g = min(round($green*$pixel['green']/169),255);
$b = min(round($blue*$pixel['blue']/169),255);
$a = $pixel['alpha'];
//echo('red : '.$pixel['red'].' => '.$r.', green : '.$pixel['green'].' => '.$g.', blue : '.$pixel['blue'].' => '.$b.', alpha : '.$pixel['alpha'].' => '.$a.'<br>');

$pixelcolor = imagecolorallocatealpha($n_im, $r, $g, $b, $a);

imagealphablending($n_im, TRUE);
imagesetpixel($n_im, $x, $y, $pixelcolor);
}
}

imagepng($n_im,'test.png');
imagedestroy($n_im);
}
0
Kae Cyphet
13 年前
如果您在嘗試擷取黑色像素時得到不一致或沒有任何意義的結果,例如

(紅色、綠色、藍色)
0,0,0
0,0,0
0,0,2
0,0,4
0,0,6
0,0,7
0,0,0
0,0,10
0,0,8
0,0,9
0,0,0
0,0,12
0,0,13
0,0,0

從使用 imagecreate() 切換到 imagecreatetruecolor()

在建立圖表時發現問題,其中像素的顏色會根據先前的顏色和新資料而增加。
0
madtrader117 at gmail dot com
14 年前
這是我建立的一個函數,用於尋找某些電影縮圖周圍黑色邊框的大小,其中電影本身為了保持長寬比而添加了黑色邊距。

<?php
define
("DEBUG_OUT",TRUE);
$border_size = find_border_size($path);
print_r($border_size);
/*
* $border = max(find_border_size("img.jpg"));
* $thumb_size_x = 180+(2*$border);
* $thumb_size_y = 240+(2*$border);
* $thumb_size = $thumb_size_x . "x" . $thumb_size_y; (String to use in the -s param of ffmpeg)
* $crop_cmd = "-croptop $border -cropbottom $border -cropright $border -cropleft $border";
*/
function find_border_size($path)
{
/* 這個 pad 變數本質上是一個「羽化」值。除非其中一個 RGB 值超過 $pad,否則我們就說繼續。你可以嘗試不同的值,但即使是 10,由於電影的邊緣滲色到帽子中,我仍然會得到一個相當大的邊框。
*/
$pad = 20;
$border_y = 0;
$border_x = 0;

if(!
file_exists($path))
{
if(
DEBUG_OUT) echo("錯誤:$path 未找到。\n");
return
FALSE;
}
else
{
if(
DEBUG_OUT) echo("開啟:$path ...\n");
}
$im = @imagecreatefromjpeg($path);
if(!
$im) return FALSE;
$height = imagesy($im);
$width = imagesx($im);

/* 讓我們從 0, 0 開始,並持續到我們遇到顏色為止 */
if(DEBUG_OUT) echo("圖片 - 高度:$height / 寬度:$width\n");
/* 邊框高度 (Y) */
$center_width = ceil($width/2);
for(
$i=0; $i<$height; $i++)
{
$rgb = imagecolorat($im,$center_width,$i);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if(
DEBUG_OUT) echo("高度:($center_width,$i) R:$r / G:$g / B:$b\n");
if(
$r >= $pad || $g >= $pad || $b >= $pad)
{
$border_y = $i;
if(
$border_y == $height) $border_y = 0;
break;
}
}

/* 邊框寬度 (X) */
$center_height = ceil($height/2);
for(
$i=0; $i<$width; $i++)
{
$rgb = imagecolorat($im,$i,$center_height);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if(
DEBUG_OUT) echo("寬度:($i,$center_width) R:$r / G:$g / B:$b\n");
if(
$r >= $pad || $g >= $pad || $b >= $pad)
{
$border_x = $i;
if(
$border_x == $width) $border_x = 0;
break;
}
}

/* 我將邊框設為 2 的倍數,因為我要將這些值傳送到 FFMpeg */
if($border_x != 0)
{
$border_x /= 2;
$border_x = round($border_x);
$border_x *= 2;
}
if(
$border_y != 0)
{
$border_y /= 2;
$border_y = round($border_y);
$border_y *= 2;
}
if(
DEBUG_OUT) echo("邊框寬度:$border_x / 邊框高度:$border_y\n");
return array(
$border_x,$border_y);
}
?>
0
Richard
16 年前
使用以下函式,你不僅可以將 24 位元的 RGB 整數轉換為對應的紅色、綠色和藍色值,還可以將 32 位元的 RGBA 整數轉換為對應的紅色、綠色、藍色和 ALPHA 值。

不僅如此,我甚至還加入了一個函式,用於將這些紅色、綠色、藍色和 alpha 值轉換回 32 位元的 RGBA 整數。

使用範例
<?php
$int
= rgba2int(255, 255, 255, 16);
echo
$int . "<br>";
$rgba = int2rgba($int);
print_r($rgba);
?>

它應該輸出的內容
285212671
陣列
(
[r] => 255
[g] => 255
[b] => 255
[a] => 16
)

<?php
function rgba2int($r, $g, $b, $a=1) {
/*
此函式會從 4 個數值 (必須為 0-255,即 8 位元) 建構一個 32 位元的整數
32 位元整數範例:00100000010001000000100000010000
前 8 位元定義 Alpha 值
接下來 8 位元定義藍色值
接下來 8 位元定義綠色值
最後 8 位元定義紅色值
*/
return ($a << 24) + ($b << 16) + ($g << 8) + $r;
}

function
int2rgba($int) {
$a = ($int >> 24) & 0xFF;
$r = ($int >> 16) & 0xFF;
$g = ($int >> 8) & 0xFF;
$b = $int & 0xFF;
return array(
'r'=>$r, 'g'=>$g, 'b'=>$b, 'a'=>$a);
}
?>
0
Scott Thompson (VBAssassin)
16 年前
我發現這個函式在想要操作現有圖片時非常有用。例如,簡單地翻轉圖片 (原始碼在此:http://www.coderprofile.com/source-code/372/ )

我經常使用的方法是逐個像素掃描圖片,對每個像素執行某種操作...然後將新建立的像素儲存到新的畫布上,準備顯示在瀏覽器中。

我發現的唯一問題是速度...因此,對於高流量使用,建議使用某種快取機制並限制處理圖片的尺寸。

誠摯問候,
Scott
0
p h o c i s [a-t] g m a i l c o m
17 年前
我認為 GD 在處理透明遮罩和 Alpha 混合時存在問題。GD 似乎認為某些圖片具有黑色遮罩透明度 (表示圖片建立在黑色遮罩而不是透明遮罩上)。

雖然「alan hogan dot com slash contact」的解決方案確實可以處理這個問題,但結果似乎...有瑕疵。每次執行都會得到不同的結果,而且並不總是最好的。

因此,我製作了一個不同的解決方案,雖然在白色背景上看起來更好並且一致,但仍然會透過將所有混合的像素與透明顏色合併,而稍微扭曲圖片。

// 載入圖片
$img = imagecreatefrompng('my_broken_png.png');

// 製作遮罩畫布
$matte = imagecreatetruecolor(16,16);
$trans_color = imagecolorallocatealpha($matte,254,254,254,0);
imagefill($matte, 0,0,$trans_color);

// 將舊圖片放在遮罩上
imagecopy($matte,$img,0,0,0,0,16,16);

// 將遮罩顏色轉換為完全透明 (混合的像素不會受到影響)
imagecolortransparent($matte,$trans_color);

// 顯示圖片
header('Content-Type: image/gif');
imagegif($matte);
0
pocze_zsolt at hotmail dot com
17 年前
這是一個直方圖延伸函式,用於獲得更好的對比度

function contrast_stretch( $img ) {
$x = imagesx($img);
$y = imagesy($img);

$min=255.0;
$max=0.0;

for($i=0; $i<$y; $i++) {
for($j=0; $j<$x; $j++) {
$pos = imagecolorat($img, $j, $i);
$f = imagecolorsforindex($img, $pos);
$gst = $f["red"]*0.15 + $f["green"]*0.5 + $f["blue"]*0.35;
if($gst>$max) $max=$gst;
if($gst<$min) $min=$gst;
}
}

$distance = $max-$min;

for($i=0; $i<$y; $i++) {
for($j=0; $j<$x; $j++) {
$pos = imagecolorat($img, $j, $i);
$f = imagecolorsforindex($img, $pos);

$red = 255*($f["red"]-$min)/$distance;
$green = 255*($f["green"]-$min)/$distance;
$blue = 255*($f["blue"]-$min)/$distance;

if($red<0) $red = 0.0;
elseif($red>255) $red=255.0;

if($green<0) $green = 0.0;
elseif($green>255) $green=255.0;

if($blue<0) $blue = 0.0;
elseif($blue>255) $blue=255.0;

$color = imagecolorresolve($img, $red, $green, $blue);
imagesetpixel($img, $j, $i, $color);
}
}
}
0
Anonymous
18 年前
//測試 JPEG 是否為灰階或彩色

function iscolor($pic_adress){


//如果 r = B = G,則像素為灰階
//範例:彩色像素 R=250, G=140 , B=19 灰階像素 R=110, G= 110, B=110

//我們檢查 10 個像素,以找出圖片是否為灰階
$tocheck = 10;

$iscolor=false;

$temp= getimagesize($pic_adress);

$x= $temp[0];
$y= $temp[1];

$im= imagecreatefromjpeg($pic_adress);

//現在檢查像素
for( $i = 0 ; $i< $tocheck && !$iscolor; $i++){


// 這裡選擇一個隨機像素
$color = imagecolorat($im,rand(0,$x),rand(0,$y));

//問題 color 是一個整數
//這個數字的十六進位檢視為 RRGGBB
// 這裡我們取得像素的藍色部分
$blue = 0x0000ff & $color;

$green = 0x00ff00 & $color;
//綠色部分我們必須向右推 8 位元才能得到可比較的結果
$green = $green >> 8;
$red =0xff0000 & $color;
//紅色部分需要被推 16 位元
$red = $red >> 16;
//如果其中一個像素不是灰階,則會中斷,你就會知道這是彩色圖片
if( $red!= $green || $green!= $blue){
$iscolor = true;
break;
}
}
return $iscolor;

}
0
swimgod
19 年前
我製作的這個函式會比較兩個 ($start-$finish) 圖片,並在「finish」圖片中更改顏色不同的像素
然後在一個圖片中將它們並排顯示

另一個功能是「display」,它會回顯文字
「50% 開啟
50% 關閉」-% 計數 (如果數字小於 1,則會進入一個十進位計數)

或輸入「2」會是
「10023 開啟
3000 關閉」-像素計數

最後一個功能是「color」
您可以在陣列中定義它
$color = array("r" => "244","g" => "122","b" => "100");

為了結束說明,我將顯示我的函式的這個「地圖」
compare($start, $finish[, $color[, $display[, $type]]])
image-url($start) - 基礎圖片 URL
image-url($finish) - 比較圖片 URL
array($color) - 具有鍵 "r"、"g"、"b" 的陣列,r 為紅色 0-255,g 為綠色 0-255,b 為藍色 0-255
bool($display) - 1 或 TRUE 會傳回比較中的文字統計資料
int($type) - 1 或 0 | 1 為 % 結果 | 0 為像素結果

<?
function compare($start, $finish, $color, $display, $type){

$im = ImageCreateFrompng($start);
$im2 = ImageCreateFrompng($finish);
$img['x'] = imagesx($im);
$img['y'] = imagesy($im);
$img2['x'] = imagesx($im2);
$img2['y'] = imagesy($im2);
if(($img['x'] == $img2['x']) && ($img['y'] == $img2['y'])){

//取得並設定圖片高度和寬度
$i = array("width" => $img['x']*2, "height" => $img['y']);
$im3 = imagecreatetruecolor($i['width'], $i['height']);
if($color){
$color = imagecolorallocate($im3, $color['r'], $color['g'], $color['b']);
}else{

$color = imagecolorallocate($im3, 255, 255, 255);
}
for($y = $img['y'];$y > 0; $y--){
for($x = $img['x'];$x > 0; $x--){
if(ImageColorAt($im, $x, $y) == ImageColorAt($im2, $x, $y)){
$on = $on+1;
$rgb = ImageColorAt($im, $x, $y);
Imagesetpixel($im3, $img['x']+$x, $y, $rgb);
}else{
$off = $off+1;
imagesetpixel($im3, $img['x']+$x, $y , $color);
}
}
}
if($display == true){
if(($type == "1") || (!$type)){
$off2 = (round(($off / $on)*10));
if(($off2 == 0) && ($off > 0)){
$off2 = round(($off / $on)*10)*10;
}
$on2 = (100-$off2);
$off2 .="%";
$on2 .="%";
}else{
$off2 = $off;
$on2 = $on;
}
echo $off2 ." 關閉<br>". $on2 ." 開啟";
}else{
imagecopy($im3, $im, 0, 0, 0, 0, $img['x'], $img['y']);
@header("Content-type: image/png");
imagepng($im3);
imagedestroy($im3);
}
imagedestroy($im);
imagedestroy($im2);
return TRUE;
}else{
return False;
}
}
?>
-1
Levi Cole
9 年前
因此,我為此函式 (imagecolorat) 編寫了我想到的最無意義的用法。

基本上,它會將給定圖片中的每個像素轉換為 <i> 標籤。您可以使用 $p 設定呈現的像素大小

<?php
$p
= 4; // 設定像素寬度/高度
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圖片轉 DOM</title>
<style>
.canvas {position: relative;}
.pixel {width: <?= 1*$p; ?>px; height: <?= 1*$p; ?>px; position: absolute; display: block;}
</style>
</head>
<body>

<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit">
</form>

<?php
if ($_FILES) {
$post_img = $_FILES['image'];
$filename = $post_img['name'];
$tmp_img = $post_img['tmp_name'];

if(
preg_match('/[.](jpg)$/', $filename)) {
$img = imagecreatefromjpeg($tmp_img);
} else if (
preg_match('/[.](gif)$/', $filename)) {
$img = imagecreatefromgif($tmp_img);
} else if (
preg_match('/[.](png)$/', $filename)) {
$img = imagecreatefrompng($tmp_img);
}

list(
$width, $height) = getimagesize($tmp_img);

echo
'<div class="canvas" style="width: '.$width*$p.'px; height: '.$height*$p.'px;">';
for (
$i = 0; $i < $height; $i++) {
$y = $i; // Get Y coords
for ($j = 0; $j < $width; $j++) {
$x = $j; // Get X coords

$rgb = imagecolorat($img, $x, $y); // Get pixel color
$rgba = imagecolorsforindex($img, $rgb);
unset(
$rgba['alpha']); // Remove Alpha channel

$bg_color = implode(', ', $rgba);
?>
<i class="pixel" style="background: rgb(<?= $bg_color; ?>); top: <?= $i*$p; ?>px; left: <?= $j*$p; ?>px;"></i>
<?php
}
}
echo
'</div>';
}
?>

</body>
</html>
-1
morten at nilsen dot com
18 年前
一種將顏色值編碼為 #rrggbb 的更好方法

<?php
printf
('#%06x',$c);
?>

或者

<?php
$rgb
= sprintf('#%06x',$c);
?>
-1
robert at future-vision dot nl
18 年前
看媽,沒有表格:)

我修改了 'hazard AT krankteil DOTTILLYDO de' 的程式碼,讓函式可以輸出一個顯示圖片的 div。

至於輸出的檔案大小,我可以說原始的 png 檔案小很多,但對於小按鈕之類的來說,這可能是一個不錯的功能。

你可以使用它的方式與 'hazard AT krankteil DOTTILLYDO de' 的程式碼相同。

小提示:每個 div 都包含一個虛假的圖片。如果沒有這個,IE 會搞砸輸出。

<?
function hexcolor($c) {
$r = ($c >> 16) & 0xFF;
$g = ($c >> 8) & 0xFF;
$b = $c & 0xFF;
return '#'.str_pad(dechex($r), 2, '0', STR_PAD_LEFT).str_pad(dechex($g), 2, '0', STR_PAD_LEFT).str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
}


function png2div($filename) {

$img = imagecreatefrompng($filename);
$width = imagesx($img);
$height = imagesy($img);
$div_width = 1;
$previous_color = 0;

$output = '<div style="position:relative;width:' . $width . 'px;height:'. $height .'px;">';

for($y = 0;$y < $height;++$y){

for($x = 0;$x < $width;++$x){

$current_color = ImageColorAt($img, $x, $y);

if($current_color == $previous_color && $x < $width-1){
++$div_width;
}
else{
$output .= '<div style="position:relative;float:left;width:' . $div_width . 'px;height:1px;background-color:' . hexcolor((($div_width > 1)? $previous_color:$current_color)) . '"><img src="bogus.gif" alt="" width="1" height="1" /></div>';
$previous_color = $current_color;
$div_width = 1;
}
}
ob_flush();
}

$output .= '</div>';

return $output;

}

?>
-1
black at scene-si dot org
14 年前
如果圖像填充了純色(rgb 0,0,0),則平均顏色將為 0,0,0,並且直方圖在 r[0]、g[0] 和 b[0] 處具有最大值。由於我們使用容差(+- 16)刪除了這些值,因此我們只剩下平均值之外的顏色。

如果刪除的顏色佔圖像的 90% 以上(我們根據平均顏色刪除 6.25-12.5% 的直方圖),那麼我們假設圖像為空白。

這會偵測任何顏色的純色填充圖像,以及顏色變化很小的圖像(空白牆、沒有雲的藍天、幾乎褪色的圖像、對比度非常低且顏色範圍低的圖像)。此函式非常適合檢查影片的影格是否為空白(如果您要產生縮圖)。

<?php
function isBlank($gd_resource, $tolerance, $percent)
{
list(
$w,$h) = array(imagesx($gd_resource), imagesy($gd_resource));

$count = 0;
$hr = $hg = $hb = array();
for (
$i=0; $i<$h; $i++) {
for (
$j=0; $j<$w; $j++) {
$pos = imagecolorat($gd_resource, $j, $i);
$f = imagecolorsforindex($gd_resource, $pos);
$hr[$f['red']] = issetor($hr[$f['red']],0) + 1;
$hg[$f['green']] = issetor($hg[$f['green']],0) + 1;
$hb[$f['blue']] = issetor($hb[$f['blue']],0) + 1;
$count ++;
}
}

$rc = array_sum($hr);
$gc = array_sum($hg);
$bc = array_sum($hb);

$r = $rc/$count;
$g = $gc/$count;
$b = $bc/$count;

$ra = range(max(0,$r-$tolerance), min(255,$r+$tolerance));
$ga = range(max(0,$g-$tolerance), min(255,$g+$tolerance));
$ba = range(max(0,$b-$tolerance), min(255,$b+$tolerance));

foreach (
$ra as $rx) {
unset(
$hr[$rx]);
}
foreach (
$ga as $gx) {
unset(
$hg[$gx]);
}
foreach (
$ba as $bx) {
unset(
$hb[$bx]);
}

$red = floatval(array_sum($hr)+1) / floatval($rc);
$green = floatval(array_sum($hg)+1) / floatval($gc);
$blue = floatval(array_sum($hb)+1) / floatval($bc);

if (
$red<$percent && $green<$percent && $blue<$percent) {
return
true;
}
return
false;
}

// Example;

isBlank($gd_resource, 16, 0.1);

?>
To Top