imagesetpixel

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

imagesetpixel设置单个像素

描述

imagesetpixel(
    GdImage $image,
    int $x,
    int $y,
    int $color
): bool

imagesetpixel() 在指定坐标处绘制像素。

参数

image

一个 GdImage 对象,由图像创建函数之一返回,例如 imagecreatetruecolor()

x

x 坐标。

y

y 坐标。

color

使用 imagecolorallocate() 创建的颜色标识符。

返回值

如果成功,则返回 true,如果失败,则返回 false

变更日志

版本 描述
8.0.0 image 现在期望一个 GdImage 实例;以前,期望一个有效的 gd 资源

示例

示例 #1 imagesetpixel() 示例

随机绘制,最后形成一幅正常的图片。

<?php

$x
= 200;
$y = 200;

$gd = imagecreatetruecolor($x, $y);

$corners[0] = array('x' => 100, 'y' => 10);
$corners[1] = array('x' => 0, 'y' => 190);
$corners[2] = array('x' => 200, 'y' => 190);

$red = imagecolorallocate($gd, 255, 0, 0);

for (
$i = 0; $i < 100000; $i++) {
imagesetpixel($gd, round($x), round($y), $red);
$a = rand(0, 2);
$x = ($x + $corners[$a]['x']) / 2;
$y = ($y + $corners[$a]['y']) / 2;
}

header('Content-Type: image/png');
imagepng($gd);

?>

上面的示例将输出类似于

Output of example : imagesetpixel()

参见

添加笔记

用户贡献笔记 24 个笔记

d [AT] sprid [DOT] de
19 年前
这段代码确实生成了一个 RGB 立方体(有或没有边界)。由于它只渲染可见像素,所以它显然很快(大约 1 到 2 秒)。通过更改 $order 变量,您可以从不同的角度查看立方体。输入双倍或三倍值(如 rrg 或 ggg)将为您提供单个通道的其他规格。任何建议请发送到我的电子邮件。

<?php
$borders
= true;
$order = 'rgb';

set_time_limit(0);
$img = imageCreateTrueColor(510, 510);

$bg = imageColorAllocate($img, 255, 255, 255);
$black = imageColorAllocate($img, 255, 255, 255);

for (
$r=0; $r<256; $r++) {
for (
$g=0; $g<256; $g++) {
for (
$b=0; $b<256; $b++) {
$rN = ${$order{0}};
$gN = ${$order{1}};
$bN = ${$order{2}};

$col = imageColorAllocate($img, $rN, $gN, $bN);
imagesetpixel($img, $b+($r*0.5)+(255/4), $g+($r*0.5)+(255/4), $col);
if (
$r < 255 && $g > 0) break;
}
}

if (
$borders) {
imagesetpixel($img, ($r*0.5+(255/4)), ($r*0.5)+(255/4), $black);
imagesetpixel($img, ($r*0.5)+255+(255/4), ($r*0.5)+(255/4), $black);
imagesetpixel($img, ($r*0.5)+(255/4), ($r*0.5)+255+(255/4), $black);
}
}

if (
$borders) {
imageline($img, 255/4, 255/4, 255+(255/4), 255/4, $black);
imageline($img, 255/4, 255/4, 255/4, 255+(255/4), $black);
imageline($img, 255*0.5+(255/4), 255*0.5+(255/4), 255*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), $black);
imageline($img, 255*0.5+(255/4), 255*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), 255*0.5+(255/4), $black);
imageline($img, 255*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), $black);
imageline($img, 255*0.5 + 509*0.5+(255/4), 255*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), 255*0.5 + 509*0.5+(255/4), $black);
}

header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
?>
guy032 at gmail dot com
12 年前
将具有白色(或接近白色)背景的图像设置为透明

<?
函数 FloodFill($im, $x, $y)
{
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

$counter=0;
$counter2=0;
if($r >= 245){ $counter++;}
if($g >= 245){ $counter++;}
if($b >= 245){ $counter++;}
if($r >= 240){ $counter2++;}
if($g >= 240){ $counter2++;}
if($b >= 240){ $counter2++;}

if($counter >= 1 && $counter2 == 3){
$background = imagecolorallocate($im, 180, 0, 255);
imagesetpixel($im, $x, $y, $background);

FloodFill ($im, $x, $y+1);
FloodFill ($im, $x+1, $y);
FloodFill ($im, $x, $y-1);
}
}

$src = $_GET["src"];
$im = imagecreatefromjpeg($src);

// 绘制边框
$border = imagecolorallocate($im, 180, 0, 255);
drawBorder($im, $border, 1);

// 绘制边框
function drawBorder($im, $color, $thickness = 1)
{
$x1 = 0;
$y1 = 0;
$x2 = ImageSX($im) - 1;
$y2 = ImageSY($im) - 1;

for($i = 0; $i < $thickness; $i++)
{
ImageRectangle($im, $x1++, $y1++, $x2--, $y2--, $color);
}
}

$rgb = imagecolorat($im, 0, 0);
FloodFill($im, 0, 0);
$color = imagecolorallocate($im, 180, 0, 255);
imagecolortransparent($im, $color);
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
?>
odin<spam inside(C)>dtdm.org
19 年前
只是一个简单的 Bresenham 算法实现(教育目的...)。

您可以在以下位置找到有关此算法和其他图形教程的更多信息: http://brand107.home.comcast.net/pc-gpe/

<?php

/****************************************************
Bresenham 直线算法 PHP/GD 实现
****************************************************/
function line($im,$x1,$y1,$x2,$y2,$color){

$deltax=abs($x2-$x1);
$deltay=abs($y2-$y1);

if (
$deltax>$deltay) {
$numpixels=$deltax+1;
$d=(2*$deltay)-$deltax;
$dinc1=$deltay << 1; $dinc2=($deltay-$deltax) << 1;
$xinc1=1; $xinc2=1;
$yinc1=0; $yinc2=1;
} else {
$numpixels=$deltay+1;
$d=(2*$deltax)-$deltay;
$dinc1=$deltax << 1; $dinc2=($deltax-$deltay)<<1;
$xinc1=0; $xinc2=1;
$yinc1=1; $yinc2=1;
}

if (
$x1>$x2) {
$xinc1=-$xinc1;
$xinc2=-$xinc2;
}

if (
$y1>$y2) {
$yinc1=-$yinc1;
$yinc2=-$yinc2;
}
$x=$x1;
$y=$y1;

for (
$i=0;$i<$numpixels;$i++) {
imagesetpixel($im,$x,$y,$color);
if (
$d<0) {
$d+=$dinc1;
$x+=$xinc1;
$y+=$yinc1;
} else {
$d+=$dinc2;
$x+=$xinc2;
$y+=$yinc2;
}
}
return ;
}

?>
mail AT kkapsner DOT de
14 年前
使用 PHP 本地确实可以“删除”图像中的像素 - 关键函数是 imageAlphaBlending
<?php

$image
= imageCreateTrueColor(101, 101);
imageSaveAlpha($image, true);

# 使用 alpha 混合绘制红色圆形
$red = imageColorAllocateAlpha($image, 255, 0, 0, 30);
imageFilledEllipse($image, 50, 50, 100, 100, $red);

# 禁用 alpha 混合以进行删除
imageAlphaBlending($image, false);

# 使用完全不透明的颜色绘制
$trans = imageColorAllocateAlpha($image, 0, 0, 0, 127);

# 你可以清除任何你喜欢的形状
imageFilledRectangle($image, 30, 30, 70, 70, $trans);

# 再次启用 alpha 混合
imageAlphaBlending($image, true);

# 使用 alpha 混合绘制绿色矩形
$green = imageColorAllocateAlpha($image, 0, 255, 0, 40);
imageFilledRectangle($image, 40, 20, 90, 80, $green);

header("Content-Type: image/png");
imagePNG($image);

?>
bpgordon at gmail dot com
19 年前
此代码将一段文本转换为图像,使文本块中的每个字符在图像中定义一个像素,文本块中的每行(由 \n 分隔)在图像中构建一整行像素。
用法:放置 0 以创建白色像素。放置 1 以创建黑色像素。
示例:输入以下数字(包括换行符)将创建一个 3x3 方形,带有 1 像素的白色边框。
00000
01110
01110
01110
00000

<?php
if (isset($_POST["sendtxt"])) {
header("Content-type: image/png");
$splitted = explode("\n", $_POST["sendtxt"]);
foreach (
$splitted as $tcurkey => $curval) $tsplitted[$tcurkey] = rtrim($curval);
$splitted = $tsplitted; //referencing isn't working for some reason...
$image = imagecreate(strlen($splitted[1]), count($splitted));
$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); // don't delete this line
$black = imagecolorallocate($image, 0x00, 0x00, 0x00);
foreach(
$splitted as $curkey => $opelement) {
$subsplitten = preg_split("//", $opelement);
foreach(
$subsplitten as $subcurkey => $subopelement) {
if (
$subopelement == "1" || $subopelement == ".") imagesetpixel($image, $subcurkey-1, $curkey, $black);
}
}
imagepng($image);
imagedestroy($image);
} else {
echo <<<end
<table width="1" border="0"><td>
<form method="post" action="#">
<textarea cols="30" rows="7" name="sendtxt"></textarea><br><br>
<input type="submit" value="渲染">
</form></td></table>
end; }
?>
gerben at gerbs dot net
6 年前
请注意,你不需要使用 imagecolorallocate 来绘制像素。相反,你可以直接分配颜色,这更快
<?php
imagesetpixel
($img, $x, $y, $r << 16 | $g << 8 | $b);
?>
CR@SH
10 年前
imagesetpixel ($image, $x, $y, IMG_COLOR_BRUSHED);
cyberhorse at users dot sourceforge dot net
14 年前
给定图像 $src 和蒙版 $mask,此代码使用不同的透明度级别将蒙版应用于图像。

<?php
function image_mask(&$src, &$mask) {
imagesavealpha($src, true);
imagealphablending($src, false);
// 扫描图像像素
for ($x = 0; $x < imagesx($src); $x++) {
for (
$y = 0; $y < imagesy($src); $y++) {
$mask_pix = imagecolorat($mask,$x,$y);
$mask_pix_color = imagecolorsforindex($mask, $mask_pix);
if (
$mask_pix_color['alpha'] < 127) {
$src_pix = imagecolorat($src,$x,$y);
$src_pix_array = imagecolorsforindex($src, $src_pix);
imagesetpixel($src, $x, $y, imagecolorallocatealpha($src, $src_pix_array['red'], $src_pix_array['green'], $src_pix_array['blue'], 127 - $mask_pix_color['alpha']));
}
}
}
}
?>

如果蒙版反转,请将 127 - $mask_pix_color['alpha'] 更改为 $mask_pix_color['alpha']
aelitadelarobia at gmail dot com
14 年前
另一个可以执行水平或垂直渐变的渐变示例

<?php
$width
=$_GET['width'];
$height=$_GET['height'];
$starts=explode(",",$_GET['startcolor']);
$ends=explode(",",$_GET['endcolor']);
$rstart=$starts[0];
$gstart=$starts[1];
$bstart=$starts[2];
$rend=$ends[0];
$gend=$ends[1];
$bend=$ends[2];
$r=$rstart;
$g=$gstart;
$b=$bstart;
$bigger=imagecreatetruecolor($width,$height);
for (
$y=0;$y<=265;$y++) {
if (
$mode == 'horiz') { // 如果执行水平渐变,则每行重置为起始颜色
$r=$rstart;
$g=$gstart;
$b=$bstart;
}
for (
$x=0;$x<=464;$x++) {
imagesetpixel($bigger,$x,$y,imagecolorallocate($bigger,$r,$g,$b));
if (
$mode=="horiz") {
if (
$r != $rend) {
$r=$r+(($rend-$rstart)/$width);
}
if (
$g != $gend) {
$g=$g+(($gend-$gstart)/$width);
}
if (
$b != $bend) {
$b=$b+(($bend-$bstart)/$width);
}
}
}
if (
$mode == "vert") {
if (
$r != $rend) {
$r=$r+(($rend-$rstart)/$height);
}
if (
$g != $gend) {
$g=$g+(($gend-$gstart)/$height);
}
if (
$b != $bend) {
$b=$b+(($bend-$bstart)/$height);
}
}
}
header("Content-type: image/jpeg");
header('Content-Disposition: inline; filename="gradient.jpg"');

imagejpeg($bigger,NULL,99);
imagedestroy($bigger);
?>
Scott Evernden (doctor3d at gmail)
15 年前
Re: imagecreatefromtga() .. 我刚刚对一些我认为有效的 Targa-24 和 Targa-32 位图像进行了测试,并修改了内部逻辑如下

<?php
if ($bytes_per_pixel == 2) // TARGA 16 - ARRRRRGG GGGBBBBB
{
$word = fileint($data, $pointer, 2);
$r = ($word & 0x7C00) >> 7;
$g = ($word & 0x03E0) >> 2;
$b = ($word & 0x001F) << 3;
$a = ($word & 0x8000) ? 127 : 0;
$color = imagecolorallocatealpha($image, $r, $g, $b, $a);
imagesetpixel($image, $x, $y, $color); }
else if (
$bytes_per_pixel == 3) // TARGA 24 - BBBBBBBB GGGGGGGG RRRRRRRR
{
$r = fileint($data, $pointer, 1);
$b = fileint($data, $pointer+1, 1);
$g = fileint($data, $pointer+2, 1);
$color = imagecolorallocate($image, $r, $g, $b);
imagesetpixel($image, $x, $y, $color);
}
else if (
$bytes_per_pixel == 4) // TARGA 32 - BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA
{
$b = fileint($data, $pointer, 1);
$g = fileint($data, $pointer+1, 1);
$r = fileint($data, $pointer+2, 1);
$a = (255 - fileint($data, $pointer+3, 1)) >> 1;
$color = imagecolorallocatealpha($image, $r, $g, $b, $a);
imagesetpixel($image, $x, $y, $color);
}
?>

这个修复了红色和蓝色色调问题...
Scott Evernden (doctor3d at gmail)
16 年前
我上一次的笔记没有正确处理 alpha,所以对相应的行进行以下更改

$r = ($word & 0x7C00) >> 7;
$g = ($word & 0x03E0) >> 2;
$b = ($word & 0x001F) << 3;
$a = ($word & 0x8000) ? 127 : 0;
$color = imagecolorallocatealpha($image, $r, $g, $b, $a);
imagesetpixel($image, $x, $y, $color);
Scott Evernden (doctor3d at gmail)
16 年前
这是我测试过的 imagecreatefromtga() 函数,适用于 targa 16,改编自 zehao dot chang at gmail dot com 提供的代码

function imagecreatefromtga($filename)
{
$data = file_get_contents($filename);

// 提取头部信息
$string_length = fileint($data, 1, 1);
$data_type = fileint($data, 2, 1);
$width = fileint($data, 12, 2);
$height = fileint($data, 14, 2);
$bits_per_pixel = fileint($data, 16, 1);

$bytes_per_pixel = (int) $bits_per_pixel / 8;

// 目前只支持 RGB 数据类型
switch ($data_type) // 头部信息来自 http://astronomy.swin.edu.au/~pbourke/dataformats/tga/
{
case 2: // 未压缩的 RGB 图像
break;
case 0: // 没有附加图像数据
case 1: // 未压缩的调色板图像
case 3: // 未压缩的黑白图像
case 9: // 运行长度编码的调色板图像
case 10: // 运行长度编码的 RGB 图像
case 11: // 压缩的黑白图像
case 32: // 压缩的调色板数据,使用霍夫曼、增量和运行长度编码
case 33: // 压缩的调色板数据,使用霍夫曼、增量和运行长度编码。 4 通道四叉树类型过程
default
return NULL; // 不支持这些类型
}

// 从头部信息中计算我们需要的内容
$pointer = 18 + $string_length;
$x = 0; $y = $height - 1;

$image = imagecreatetruecolor($width, $height);

while ($pointer < strlen($data))
{
if ($bytes_per_pixel == 2) // TARGA 16 - ARRRRRGG GGGBBBBB
{
$word = fileint($data, $pointer, 2);
$r = ($word & 0x7C00) >> 10;
$g = ($word & 0x03E0) >> 5;
$b = ($word & 0x001F);
imagesetpixel($image, $x, $y, $r << 19 | $g << 11 | $b << 3);
}
else if ($bytes_per_pixel == 3) // TARGA 24 - RRRRRRRR GGGGGGGG BBBBBBBB
{
imagesetpixel($image, $x, $y, fileint($data, $pointer, 3));
}
else if ($bytes_per_pixel == 4) // TARGA 32 - AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
{
imagesetpixel($image, $x, $y, fileint($data, $pointer + 1, 3));
}

if (++$x == $width)
{
$y--;
$x = 0;
}
$pointer += $bytes_per_pixel;
}

return $image;
}

function fileint($data, $pos, $len)
{
return base_convert(bin2hex(strrev(substr($data, $pos, $len))), 16, 10);
}
zehao dot chang at gmail dot com
18 年前
这是我对 imagecreatefromtga 函数的尝试。我使用来自 send at mail dot 2aj dot net 和其他人的代码作为基础,并添加了对 targa 16、targa 24 和 targa 32 的支持。但是,我只支持未压缩的 RBG 数据类型,因为这是我目前唯一需要的类型。(我删除了 return_array 功能,因为你可以简单地使用 imagesx() 和 imagesy() 来获取图像大小)。

请注意,我没有用 targa 16 测试过,因为我目前手头没有。

<?php

function imagecreatefromtga( $filename )
{
$handle = fopen( $filename, 'rb' );
$data = fread( $handle, filesize( $filename ) );
fclose( $handle );

// 提取头部信息
$string_length = base_convert( bin2hex( substr($data,1,1) ), 16, 10 );
$data_type = base_convert( bin2hex( substr($data,2,1) ), 16, 10 );
$width = base_convert( bin2hex( strrev( substr($data,12,2) ) ), 16, 10 );
$height = base_convert( bin2hex( strrev( substr($data,14,2) ) ), 16, 10 );
$bits_per_pixel = base_convert( bin2hex( substr($data,16,1) ), 16, 10 );

// 目前只支持 RGB 数据类型
switch( $data_type ) // 头部信息来自 http://astronomy.swin.edu.au/~pbourke/dataformats/tga/
{
case
2: // 未压缩的 RGB 图像
break;
case
0: // 没有附加的图像数据
case 1: // 未压缩的颜色映射图像
case 3: // 未压缩的黑白图像
case 9: // 运行长度编码的颜色映射图像
case 10: // 运行长度编码的 RGB 图像
case 11: // 压缩的黑白图像
case 32: // 压缩的颜色映射数据,使用霍夫曼、差值和运行长度编码
case 33: // 压缩的颜色映射数据,使用霍夫曼、差值和运行长度编码。 四次四叉树类型处理
default:
return
NULL; // 不支持这些类型
}

// 计算我们从头部信息中需要的东西
$pointer = 18 + $string_length;
$bytes_per_pixel = (int) $bits_per_pixel/8;
$x = 0; $y = $height;

$image = imagecreatetruecolor($width, $height);

while (
$pointer < strlen($data) )
{
if(
$bytes_per_pixel == 2 ) // TARGA 16 - ARRRRRGG GGGBBBBB
{
$low_byte = bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel)));
$high_byte = bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel)));
$r = base_convert( ($high_byte & 0x7C)>>2, 16, 10);
$g = base_convert( (($high_byte & 0x03)<<3) | (($low_byte & 0xE0)>>5), 16, 10);
$b = base_convert( $low_byte & 0x1F, 16, 10);
imagesetpixel( $image, $x, $y, $r<<16 | $g<<8 | $b);
}
else if(
$bytes_per_pixel == 3 ) // TARGA 24 - RRRRRRRR GGGGGGGG BBBBBBBB
{
imagesetpixel( $image, $x, $y, base_convert( bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel))), 16, 10));
}
else if(
$bytes_per_pixel == 4 ) // TARGA 32 - AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
{
imagesetpixel( $image, $x, $y, base_convert( bin2hex( strrev( substr($data, $pointer, $bytes_per_pixel-1))), 16, 10));
}

if(++
$x == $width)
{
$y--;
$x=0;
}
$pointer += $bytes_per_pixel;
}

return
$image;
}

?>
T. Dekker
18 年前
回复 weitheism at gmail.com

你应该在早期尝试中使用 ImageAlphaBlending($image, false);。这样,任何绘制/填充操作都会替换目标的 alpha 值。
chris at drunkenpirates dot co dot uk
20 年前
<?php

/*
将 ImageColorAllocate、Imagesetpixel、Imagecopyresized 和一些基本的三角函数结合使用的示例

作者:[email protected]

*/

Header("Content-type: image/png");

$height = 128;
$width = 128;

$imA = ImageCreate($width, $height);
$imB = ImageCreate($width*4, $height*4);
$bckA = ImageColorAllocate($imA, 0,0,0);
$bckB = ImageColorAllocate($imB, 0,0,0);

//生成灰度调色板

for($c=0;$c<256;$c++){
ImageColorAllocate($imA, $c, $c, $c);
}

//生成数据

$m=rand(0,10);
for(
$c=0;$c<128;$c++){
$s= (sin( deg2rad($c*360*$m/128) )+1)*127;
$col_arr[$c]=$s;
}
for(
$y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgA[$x][$y]=$col_arr[$x];
}
}
for(
$y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgB[$x][$y]=$col_arr[$y];
}
}

//设置像素

for($y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgC[$x][$y]=$imgA[$x][$y]+$imgB[$x][$y];
$s=$imgC[$x][$y]/2;
Imagesetpixel($imA,$x,$y,$s);
}
}

//调整图像大小以进行显示

Imagecopyresized ($imB, $imA, 0, 0, 0, 0, $width*4, $height*4, $width, $width);
ImagePNG($imB);
?>
dino at nordmark dot dk
22 年前
上面的示例由于一些错误而无法正常工作。
这个应该可以工作,而且速度更快,因为只有一个 512*512 循环。(但它仍然很慢)

<?
$filename="lena.raw";
$width=512;
$height=512;
$fp=fopen($filename, "r");
$contents=fread($fp,filesize($filename));
fclose($fp);

$image=imagecreate($width,$height);

// 创建灰度调色板,因为图像被限制为 256 种颜色
for ($i=0;$i<256;$i++){ ImageColorAllocate($image,$i,$i,$i);}

// 速度很慢,但可能是唯一的方法
for ($i=0;$i<512;$i++){
for ($j=0;$j<512;$j++){
imagesetpixel ($image,$i,$j,ord($contents[$i+$j*512]));
}
}

imagepng($image,"result.png");
imagedestroy($image);

echo "<img src=result.png></img>";
?>

--

Dino Patti
caffinated
14 年前
想用这个函数玩点有趣的东西吗?试试边缘检测!(从 http://bitecode.co.uk/2008/07/edge-detection-in-python/ 移植而来)

<?php
function edge($input, $output)
{
$in_im = imageCreateFromJpeg($input);
$gx = array(array(-1, 0, 1), array(-2, 0, 2), array(-1, 0, 1));
$gy = array(array(-1, -2, -1), array(0, 0, 0), array(1, 2, 1));
$x = imagesx($in_im);
$y = imagesy($in_im);
$out_im = imagecreatetruecolor($x, $y);
$colors = array(255 => imagecolorallocate($out_im, 255, 255, 255));
for (
$row = 1; $row < $x; $row++)
{
for (
$col = 1; $col < $y; $col++)
{
$eyedropper =imagecolorat($in_im, $x, $y);
$color =imagecolorsforindex($in_im, $eyedropper);
$pxval = ($color['red'] + $color['green'] + $color['blue']) / 3;
$pixel_gx = $pixel_gy = 0;
for (
$i = -1; $i < 2; $i++)
{
for (
$j = -1; $j < 2; $j++)
{
$eyedropper =imagecolorat($in_im, $row+$i, $col+$j);
$color =imagecolorsforindex($in_im, $eyedropper);
$val = ($color['red'] + $color['green'] + $color['blue']) / 3;
$pixel_gx += $gx[$i+1][$j+1] * $val;
$pixel_gy += $gy[$i+1][$j+1] * $val;
}
}
$pixel = sqrt($pixel_gx * $pixel_gx + $pixel_gy * $pixel_gy);
$pixel = abs(255 - (int)$pixel);
if (!isset(
$colors[$pixel])) $colors[$pixel] = imagecolorallocate($out_im, $pixel, $pixel, $pixel);
imageSetPixel($out_im, $row, $col, $colors[$pixel]);
}
}
imagejpeg($out_im,$output, 75);
}

edge('input.jpg', 'output.jpg');

?>
CPHaxer
15 年前
抱歉我的函数介绍太长了,我只是想说明它是如何工作的,以及一些实现这种函数的想法是多么荒谬。玩得开心;D

<?php

//@函数名: drawPlot
//@参数: drawPlot(img &$image, int $red, int $green, int $blue, int $x, int $y)
//
// img $image
// 将在其上绘制的图像。图像将被修改;没有返回值。
//
// int $red, int $green, int $blue
// 用于绘制的颜色值
//
// int $x, int $y
// 绘制点的坐标。
// 这也是重点,因为 $x 和 $y
// 不需要四舍五入!
// 如果您想在 [253.643891, 482] 处绘制一个点;
// 它会绘制在该点。正好在坐标处。
// 您可以用它来制作平滑的线。
// 它们也有有理坐标。
//
//@作者: Alexander Rath (*1996 年 2 月 9 日;13 岁)
//
//@想法: 我们现在在数学几何中。作为班上唯一的电脑迷,
// 我问自己:"如果镜像一个
// 不是平面的线呢?"
// 所以我就开始思考它。首先我想到的是度数——不行!
// 然后我看到了:
// 要镜像的点到线的最短距离;
// 所以只需要让结果平滑即可。
// 与其他绘制像素的方法不同。
// ~我开始开发这个:
// PS:抱歉英语不好(我是德国人)

// 创建一个 TrueColor 图像资源
$image = imagecreatetruecolor(640, 480);

// 设置 Alpha 通道
imagealphablending($image, true);
imagesavealpha($image, true);

//... 用白色背景绘制。
imagefilledrectangle($image, 0, 0, 640, 480, imagecolorallocate($image, 255, 255, 255));

// 这是我的小 "例子" 脚本
for($x = 0; $x <= 640; $x = $x + 0.01) {
$y = $x / (tan($x) + 1);
drawPlot($image, 0, 0, 0, $x, $y);
}

header("Content-type: image/png");
imagepng($image);

function
drawPlot(&$func_image, $func_red, $func_green, $func_blue, $func_x, $func_y) {
$func_Right = $func_x - floor($func_x);
$func_Left = 1 - $func_Right;

$func_Bottom = $func_y - floor($func_y);
$func_Top = 1 - $func_Bottom;

$func_RightAlpha = $func_Right * 127;
$func_LeftAlpha = $func_Left * 127;

$func_LeftTop = $func_LeftAlpha * $func_Top;
$func_RightTop = $func_RightAlpha * $func_Top;
$func_LeftBottom = $func_LeftAlpha * $func_Bottom;
$func_RightBottom = $func_RightAlpha * $func_Bottom;

$func_x = floor($func_x);
$func_y = floor($func_y);

imagesetpixel($func_image, $func_x, $func_y, imagecolorallocatealpha($func_image, $func_red, $func_green, $func_blue, 127 - $func_LeftTop));
imagesetpixel($func_image, $func_x + 1, $func_y, imagecolorallocatealpha($func_image, $func_red, $func_green, $func_blue, 127 - $func_RightTop));
imagesetpixel($func_image, $func_x + 1, $func_y + 1, imagecolorallocatealpha($func_image, $func_red, $func_green, $func_blue, 127 - $func_RightBottom));
imagesetpixel($func_image, $func_x, $func_y + 1, imagecolorallocatealpha($func_image, $func_red, $func_green, $func_blue, 127 - $func_LeftBottom));
}

?>

玩得开心;D
mm
15 年前
@ Scott Evernden

Scott,您的函数对于未压缩的 TGA 图像文件非常有效,但 TGA 32 带 alpha 的结果在我的测试中不正确。如果 alpha 全部是白色,则生成的图像会呈现红色色调。如果为黑色,则生成的图像会呈现蓝色色调。我不知道如何让它忽略 alpha,但这会很方便...
Gusts Kaksis
17 年前
此代码生成一个简单的颜色表 - 不是一个非常准确的表(最好定义颜色的淡入 - 更多淡入)

<?php
set_time_limit
(200);
/*
自定义以查看一些不错的变化:
*/
$width = 360; // 度
$height = 18; // 字节
$offset = -60; // 颜色色调偏移量

/*
主程序:
以下是转换 - 宽度转换为度,高度转换为强度
*/
$w2deg = $width/360;
$h2byte = $height/255;
$byte2deg = 255/360;
$im = imagecreatetruecolor($width,$height);
for (
$x = 0; $x < $width; $x ++){
/*
将 X 转换为度
*/
$x_pos = $x/$w2deg;
/*
在 360 度刻度上的强度位置(最大强度为 255)。
0 = 红色
1 = 绿色
2 = 蓝色
*/
$rgb_pos[0] = sin(deg2rad($x_pos) - deg2rad($offset + 0));
$rgb_pos[1] = sin(deg2rad($x_pos) - deg2rad($offset + 120));
$rgb_pos[2] = sin(deg2rad($x_pos) - deg2rad($offset + 240));
/*
计算当前点处的强度 0 - 255
*/
$rgb_col[0] = 127 + 127 * $rgb_pos[0];
$rgb_col[1] = 127 + 127 * $rgb_pos[1];
$rgb_col[2] = 127 + 127 * $rgb_pos[2];

/*
白色 -> 颜色 -> 黑色循环
*/
for ($y = 0; $y < $height; $y ++){
/*
将 Y 转换为强度(-255 到 255)
*/
$y_pos = -255 + ($y/$h2byte) * 2;
$rgb_out[0] = $rgb_col[0] - $y_pos;
$rgb_out[1] = $rgb_col[1] - $y_pos;
$rgb_out[2] = $rgb_col[2] - $y_pos;

/*
如果超过 255 或低于 0,则将其归一化
*/
foreach($rgb_out as $key => $col){
if (
$col > 255){
$rgb_out[$key] = 255;
} else if (
$col < 0){
$rgb_out[$key] = 0;
}
}
/*
放置像素
*/
$col = imagecolorallocate($im,$rgb_out[0],$rgb_out[1],$rgb_out[2]);
imagesetpixel($im,$x,$y,$col);
}
}
/*
测试输出
*/
imagejpeg($im,'colortable.jpg');
echo
'<img src="colortable.jpg">';
?>
Brian Vaughn [php at boynamedbri dot com]
18 年前
我查看了,但找不到任何使用包含 alpha 透明度的水印对图像加水印的示例代码。因此,以下类正是这样做的。它将两个图像对象作为参数:主图像和水印图像(可以是 gif、png 等) - 以及可选的 alpha 设置(水印图像的 0-100% alpha)。然后它创建一个新图像并将其返回,该图像将 alpha 透明水印叠加在较大图像上,并居中对齐。

<?php
class watermark{

function
create_watermark( $dst_img, $watermark_img, $alpha = 100 ) {
$alpha /= 100; # 将用户友好的 0-100% 透明度转换为小数

# 计算图像尺寸
$dst_img_w = imagesx( $dst_img );
$dst_img_h = imagesy( $dst_img );
$watermark_img_w = imagesx( $watermark_img );
$watermark_img_h = imagesy( $watermark_img );

# 创建一个新的图像来保存合并后的更改
$return_img = imagecreatetruecolor( $dst_img_w, $dst_img_h );
# $return_img = imagecreate( $dst_img_w, $dst_img_h );

# 确定中心位置坐标
$dst_img_min_x = floor( ( $dst_img_w / 2 ) - ( $watermark_img_w / 2 ) );
$dst_img_max_x = ceil( ( $dst_img_w / 2 ) + ( $watermark_img_w / 2 ) );
$dst_img_min_y = floor( ( $dst_img_h / 2 ) - ( $watermark_img_h / 2 ) );
$dst_img_max_y = ceil( ( $dst_img_h / 2 ) + ( $watermark_img_h / 2 ) );

# 遍历主图像
for( $y = 0; $y < $dst_img_h; $y++ ) {
for(
$x = 0; $x < $dst_img_w; $x++ ) {
$return_color = NULL;

# 确定水印图像中的正确像素位置
$watermark_x = $x - $dst_img_min_x;
$watermark_y = $y - $dst_img_min_y;

# 获取两个图像的颜色信息
$dst_rgb = imagecolorsforindex( $dst_img, imagecolorat( $dst_img, $x, $y ) );

# 如果水印图像在当前像素交叉点处具有非透明值
# 并且我们仍然在水印图像的边界内
if ( $watermark_x >= 0 && $watermark_x < $watermark_img_w &&
$watermark_y >= 0 && $watermark_y < $watermark_img_h ) {
$watermark_rbg = imagecolorsforindex( $watermark_img, imagecolorat( $watermark_img, $watermark_x, $watermark_y ) );

# 使用图像透明度和用户指定的透明度,计算平均值
$watermark_alpha = round( ( ( 127 - $watermark_rbg['alpha'] ) / 127 ), 2 );
$watermark_alpha = $watermark_alpha * $alpha;

# 计算两个颜色之间的“平均值” - 同时考虑指定的透明度级别
$avg_red = $this->get_ave_color( $dst_rgb['red'], $watermark_rbg['red'], $watermark_alpha );
$avg_green = $this->get_ave_color( $dst_rgb['green'], $watermark_rbg['green'], $watermark_alpha );
$avg_blue = $this->get_ave_color( $dst_rgb['blue'], $watermark_rbg['blue'], $watermark_alpha );

# 使用我们确定的平均 RGB 值计算颜色索引值
$return_color = $this->imagegetcolor( $return_img, $avg_red, $avg_green, $avg_blue );

# 如果我们这里没有处理平均颜色,那么让我们只复制主颜色
} else {
$return_color = imagecolorat( $dst_img, $x, $y );

}
# END if watermark

# 将适当的颜色绘制到返回图像上
imagesetpixel( $return_img, $x, $y, $return_color );

}
# END for each X pixel
} # END for each Y pixel

# 返回结果的带水印图像以供显示
return $return_img;

}
# END create_watermark()

# 给定透明度,平均两种颜色
function get_ave_color( $color_a, $color_b, $alpha ) {
return
round( ( ( $color_a * ( 1 - $alpha ) ) + ( $color_b * $alpha ) ) );
}
# END get_ave_color()

# 返回最接近调色板颜色的 RGB 值匹配
function imagegetcolor($im, $r, $g, $b) {
$c=imagecolorexact($im, $r, $g, $b);
if (
$c!=-1) return $c;
$c=imagecolorallocate($im, $r, $g, $b);
if (
$c!=-1) return $c;
return
imagecolorclosest($im, $r, $g, $b);
}
# EBD imagegetcolor()

} # END watermark API
?>
weitheism at gmail.com
19 年前
我一直在寻找一种方法来实际删除图像资源中的像素、正方形或图像的一部分,起初我以为 imagesetpixel 可以做到。不幸的是,它只是在那个像素上重新绘制,据我所知,php 没有原生方法可以从图像中删除部分 - 所以这个小方法应该可以删除图像中的矩形部分!

function deleteRectangle(&$oldImage,$leftX,$leftY,$rightX,$rightY)
{
// 由于 php 没有原生方法可以删除图像的一部分
// 我们必须将图像分成四个不同的部分,然后手动将它们复制到新的图像中
// 图像

$xSize = imagesx($oldImage);
$ySize = imagesy($oldImage);

// 将图像分成四个部分以进行复制
$imagesection = array();
$imagesection[] = array(0,0,$leftX,$ySize);
$imagesection[] = array($leftX,0,$rightX+1,$leftY);
$imagesection[] = array($leftX,$rightY+1,$rightX+1,$ySize);
$imagesection[] = array($rightX+1,0,$xSize,$ySize);

// 创建新的复制图像
$newImage = imagecreatetruecolor($xSize,$ySize);
// 对透明度至关重要
imagesavealpha($newImage,true);

// 用透明色填充背景
$transparentBackground = imagecolorallocatealpha($newImage,255,255,255,127);
imagefill($newImage,0,0,$transparentBackground);

// 将四个图像部分中的每一个复制到它们各自的旧位置
for($i = 0;$i<count($imagesection);$i++)
imagecopyresampled($newImage,$oldImage, $imagesection[$i][0],$imagesection[$i][1], $imagesection[$i][0],$imagesection[$i][1], $imagesection[$i][2]-$imagesection[$i][0], $imagesection[$i][3]-$imagesection[$i][1], $imagesection[$i][2]-$imagesection[$i][0], $imagesection[$i][3]-$imagesection[$i][1]);

// 或者,您可以遍历图像中的每个像素,看看该像素是否在该区域内
// 但这可能更密集
imagedestroy($oldImage);

// 将旧图像设置为新的、已清除的图像
$oldImage = $newImage;
}

它是用透明背景设计的,但您可以轻松地通过将 imagecreatetruecolor 更改为 imagecreate 并删除处理透明度的代码来更改它。希望对您有所帮助!
richard at mf2fm dot co dot uk
19 年前
这是一个接受图像 ($im) 并返回对比度最大化的图像的函数...

<?php
function contrast($im) {
$brightness=0;
$maxb=0;
$minb=255;
$imagesize=getimagesize($im);
$w=$imagesize[0];
$h=$imagesize[1];
for (
$x=0; $x<$w; $x++) {
for (
$y=0; $y<$h; $y++) {
$rgb=imagecolorat($im, $x, $y);
$rgb=imagecolorsforindex($im, $rgb);
$grey=0.2125*$rgb['red']+
0.7154*$rgb['green']+
0.0721*$rgb['blue'];
$brightness+=$grey;
if (
$grey>$maxb) $maxb=$grey;
if (
$grey<$minb) $minb=$grey;
}
}
$brightness=$brightness/($w*$h);
$minb=$brightness/($brightness-$minb);
$maxb=(255-$brightness)/($maxb-$brightness);
$contrast=min($minb, $maxb);
for (
$x=0; $x<$w; $x++) {
for (
$y=0; $y<$h; $y++) {
$rgb=imagecolorat($im, $x, $y);
$rgb=imagecolorsforindex($im, $rgb);
imagesetpixel($im, $x, $y,
65536*floor(min($rgb['red']*$contrast, 255))+
256*floor(min($rgb['green']*$contrast, 255))+
floor(min($rgb['blue']*$contrast, 255)));
}
}
return (
$im);
}
?>

使用方法示例
<?php
$imagefile
="/path/filename";
$image=imagecreatefromjpeg($imagefile);
$image=contrast($image);
imagejpeg($image, $imagefile);
?>
Anonymous
16 年前
此代码段根据 RGB 分量的值创建渐变图像。渐变允许您的页面具有阴影效果。

<?php
try{
if(!
$image=imagecreatetruecolor(50,10)){
throw new
Exception('Error creating image');
}

for(
$y=0;$y<10;++$y)
{
$color=imagecolorallocate($image, 75+($y*5),75+($y*11),75+($y*9));
for(
$x=0;$x<50;++$x)
{
imagesetpixel($image,$x,$y,$color);
}
}

//header("Content-type: image/jpeg");
imagejpeg($image,'footerShadow.jpg');
// 释放内存
imagedestroy($image);

}
catch(
Exception $e){
echo
$e->getMessage();
exit();
}
?>
To Top