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 个笔记

Luciano Ropero
17 年前
我创建了一个函数,它计算给定图像资源的平均颜色,并以 "#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;
}

虽然,我注意到你也可以通过生成一个 1px x 1px 的副本使用 imagecopyresampled 来获得一个相当好的平均颜色(生成的像素使用平均颜色着色)。
alan hogan dot com slash contact
16 年前
正如 creamdog 之前所说,alpha 通道是可用的! (手册可能需要更新以包含此信息!)

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

$alpha 然后将包含透明度(而不是不透明度)级别。所以 127(最大值)将是完全透明的,0 将是完全不透明的。

使用此信息,可以编写一个像下面完全有效的简单 dithering png-to-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

?>
mumig at poczta dot onet dot pl
20 年前
对于具有真彩色的 png 图像和调色板 png 图像,imagecolorat() 的工作方式不同 - 对于真彩色,它返回颜色的值,对于调色板,它返回索引号,您需要使用 imagecolorsforindex() 来获取 rgb 颜色值。
justin at hoogs dot com dot au
12 年前
trimImage ( resource $image , int $colour , int $tolerance )

trimImage() 将返回图像中所需像素的最顶部、最右边、最底部和最左边位置(即找到最小图像区域,这样您就可以从图像的外边缘修剪给定颜色)。

参数

image
由图像创建函数(如 imagecreatetruecolor())返回的图像资源。

颜色
要“修剪”的颜色。允许范围为 0(黑色)到 255(白色)。如果为 null(或在 0-255 之外),将使用左上角颜色作为默认值。

容差
与颜色相差 +- 的可接受范围。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>
Ray.Paseur sometimes uses Gmail
7 年前
imageColorAt() 会发出通知并返回 FALSE,因为像素坐标超出了边界。
justin at hoogs dot com dot au
10 年前
这改进了我之前的函数(它实际上只适用于几种灰度颜色)。颜色现在应该是一个十六进制颜色值。颜色和容差现在是可选参数。

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

trimImage() 将返回图像中所需像素的最顶部、最右边、最底部和最左边位置(即找到最小图像区域,这样您就可以从图像的外边缘修剪给定颜色)。

参数

image
由图像创建函数(如 imagecreatetruecolor())返回的图像资源。

颜色
要“修剪”的颜色值。如果省略,将使用左上角颜色作为默认值。

容差
与颜色相差 +- 的可接受范围。允许范围为 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);
}
dewi at dewimorgan dot com
9 年前
要测试是否将此函数的返回值作为 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']);
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 透明

?>
T. Dekker
18 年前
在 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 调色板条目存储其中。该整型是正数还是负数告诉我们该调色板条目是否启用了抗锯齿。
Super Moi
18 年前
以下是对改变色调的贡献。

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

在创建图形时发现问题,其中像素颜色会根据之前的颜色和新数据而增加。
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)
{
/* The pad var is essentially a 'feather' value. Unless one of the RGB values rises
* above $pad we are saying to continue. You can try different values but with 10 I
* would still get a decent sized border due to the bleedover of the movie into
* the hat.
*/
$pad = 20;
$border_y = 0;
$border_x = 0;

if(!
file_exists($path))
{
if(
DEBUG_OUT) echo("Error: $path not found.\n");
return
FALSE;
}
else
{
if(
DEBUG_OUT) echo("Opening: $path ...\n");
}
$im = @imagecreatefromjpeg($path);
if(!
$im) return FALSE;
$height = imagesy($im);
$width = imagesx($im);

/* Let's start at 0, 0 and keep going till we hit a color */
if(DEBUG_OUT) echo("Image - Height: $height / Width: $width\n");
/* Border Height(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("Height: ($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;
}
}

/* Border Width(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("Width: ($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;
}
}

/* I am making the border a multiple of 2 since I am sending these values to 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 Width: $border_x / Border Height: $border_y\n");
return array(
$border_x,$border_y);
}
?>
Richard
15 年前
使用以下函数,您可以将 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) {
/*
This function builds a 32 bit integer from 4 values which must be 0-255 (8 bits)
Example 32 bit integer: 00100000010001000000100000010000
The first 8 bits define the alpha
The next 8 bits define the blue
The next 8 bits define the green
The next 8 bits define the red
*/
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);
}
?>
Scott Thompson (VBAssassin)
16 年前
我发现这个函数在想要操作现有图像时非常有用。一个例子是简单地翻转图像(源代码在这里:http://www.coderprofile.com/source-code/372/

我经常使用的一个原理是逐像素扫描图像,对每个像素执行某种操作...然后将新创建的像素保存到一个新的画布上,准备显示在浏览器中。

我发现唯一的问题是速度...因此建议对于高流量使用,某种缓存机制和图像处理尺寸限制是必需的。

此致,
Scott
p h o c i s [a-t] g m a i l c o m
16 年前
我相信 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);
pocze_zsolt at hotmail dot com
16 年前
这是一个直方图拉伸函数,用于获得更好的对比度

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);
}
}
}
Anonymous
17 年前
// 测试 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;

}
swimgod
18 年前
我创建的这个函数将比较两个(开始 - 结束)图像,并更改“结束”图像中颜色不同的像素
然后将它们并排显示在一个图像中

另一个功能是“display”,它将回显文本
“50% on
50% off” - % 计数(如果数字小于 1,它将进入一位小数计数)

或者输入“2”将是
“10023 on
3000 off” - 像素计数

最后一个功能是“color”
你在数组中定义它
$color = array("r" => "244", "g" => "122", "b" => "100");

为了结束描述,我将展示这个函数的“map”
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 ." off
" . $on2 ." on";
}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;
}
}
?>
Levi Cole
9 年前
所以,我写了这个函数(imagecolorat)我能想到的最无用的用途。

它基本上将给定图像中的每个像素转换为一个 标签。你可以使用 $p 设置渲染像素的大小

<?php
$p
= 4; // 设置像素宽度/高度
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Image to 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; // 获取 Y 坐标
for ($j = 0; $j < $width; $j++) {
$x = $j; // 获取 X 坐标

$rgb = imagecolorat($img, $x, $y); // 获取像素颜色
$rgba = imagecolorsforindex($img, $rgb);
unset(
$rgba['alpha']); // 删除 Alpha 通道

$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>
morten at nilsen dot com
17 年前
一种更好的将颜色值编码为 #rrggbb 的方法

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

或者

<?php
$rgb
= sprintf('#%06x',$c);
?>
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;

}

?>
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;
}

// 例子;

isBlank($gd_resource, 16, 0.1);

?>
To Top