PHP Conference Japan 2024

imagecopymergegray

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

imagecopymergegray复制并合并图像的一部分,并使用灰度

描述

imagecopymergegray(
    GdImage $dst_image,
    GdImage $src_image,
    int $dst_x,
    int $dst_y,
    int $src_x,
    int $src_y,
    int $src_width,
    int $src_height,
    int $pct
): bool

imagecopymergegray()src_image 的一部分复制到 dst_image 上,从坐标 src_xsrc_y 开始,宽度为 src_width,高度为 src_height。定义的部分将复制到坐标 dst_xdst_y 上。

此函数与 imagecopymerge() 相同,区别在于合并时它通过在复制操作之前将目标像素转换为灰度来保留源的色调。

参数

dst_image

目标图像资源。

src_image

源图像资源。

dst_x

目标点的 x 坐标。

dst_y

目标点的 y 坐标。

src_x

源点的 x 坐标。

src_y

源点的 y 坐标。

src_width

源宽度。

src_height

源高度。

pct

src_image 将根据 pct 转换为灰度,其中 0 为完全灰度,100 为不变。当 pct = 100 时,此函数的行为与 imagecopy() 对调色板图像的行为相同,除了忽略 alpha 分量外,同时它对真彩色图像实现了 alpha 透明度。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 描述
8.0.0 dst_imagesrc_image 现在期望 GdImage 实例;以前,期望的是 resource

示例

示例 #1 imagecopymergegray() 用法

<?php
// 创建图像实例
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// 复制并合并 - 灰度 = 20%
imagecopymergegray($dest, $src, 10, 10, 0, 0, 100, 47, 20);

// 输出并释放内存
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);
?>

添加注释

用户贡献注释 8 条注释

1
amezghal at msn dot com
16 年前
灰色效果 :)
<?php
header
('content-type:image/png');
$url_img = 'my_image.png';
$img = imagecreatefrompng($url_img);
$x = imagesx($img);
$y = imagesy($img);
$gray_img = imagecreatetruecolor($x, $y);
imagecolorallocate($gray_img, 0, 0, 0);
for (
$i = 0; $i < $x; $i++) {
for (
$j = 0; $j < $y; $j++) {
$rgb = imagecolorat($img, $i, $j);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
//for gray mode $r = $g = $b
$color = max(array($r, $g, $b));
$gray_color = imagecolorexact($new_img, $color, $color, $color);
imagesetpixel($gray_img, $i, $j, $gray_color);
}
}
?>
1
Mark Barba
19 年前
// 使用我在 php.net 上找到的相同代码,
// 我能够弄清楚如何将 GIF(或 GD 支持的任何其他
// 格式)转换为 CIP 格式。CIP 是 Cisco IP 电话的图像
// 格式... 7905/7940 和 7960
// 型号... 希望有人发现这很有用并使其
// 更好...

/////// GIF2CIP PHP 代码 ///////

// 将内存中的图像转换为灰度
$img_width = imageSX($im2);
$img_height = imageSY($im2);

// 转换为灰度
// 注意:这不会影响您的原始图像,除非
// originalFileName 和 destinationFileName 相同
for ($y = 0; $y <$img_height; $y++) {
for ($x = 0; $x <$img_width; $x++) {
$rgb = imagecolorat($im2, $x, $y);
$red = ($rgb >> 16) & 0xFF;
$green = ($rgb >> 8) & 0xFF;
$blue = $rgb & 0xFF;

$gray = round(.299*$red + .587*$green + .114*$blue);

// 将灰度值左移
$grayR = $gray << 16; // R: 红色
$grayG = $gray << 8; // G: 绿色
$grayB = $gray; // B: 蓝色

// 使用或运算计算灰度值
$grayColor = $grayR | $grayG | $grayB;

// 设置像素颜色
imagesetpixel ($im2, $x, $y, $grayColor);
imagecolorallocate ($im2, $gray, $gray, $gray);
}
}
/////////////////////////////////////////////////////////

// 将调色板修改为仅4种颜色(7905/7940和7960上的CIP图像为2位颜色)
ImageTrueColorToPalette2($im2,FALSE,4);

// CIP图像文件的基本头部...
header ("Content-type: text/xml");
echo "<CiscoIPPhoneImage> ";
echo "<LocationX>-1</LocationX> ";
echo "<LocationY>-1</LocationY> ";
echo "<Width>132</Width> ";
echo "<Height>65</Height> ";
echo "<Depth>2</Depth> ";
echo "<Data>";

// 获取图像尺寸(与上面代码几乎相同)
$img_width = imageSX($im2);
$img_height = imageSY($im2);

// 转换为灰度
// 注意:这不会影响您的原始图像,除非
// originalFileName 和 destinationFileName 相同
for ($y = 0; $y <$img_height; $y++) {
for ($x = 0; $x+4 <$img_width; $x = $x+4)
{
for ($ix = 0; $ix < 4; $ix++)
{
$rgb = imagecolorat($im2, $x + $ix, $y);

// 我自己想出了这个转换
// 一定会有聪明人把它完善
if ($rgb=="2") {$rgb=0;$Gray1[$ix] = $rgb;continue;}
if ($rgb=="0") {$rgb=2;$Gray1[$ix] = $rgb;continue;}
if ($rgb=="1") {$rgb=1;$Gray1[$ix] = $rgb;continue;}
if ($rgb=="3") {$rgb=3;$Gray1[$ix] = $rgb;continue;}
}
$gray1 = $Gray1[0];
$gray2 = $Gray1[1] << 2;
$gray3 = $Gray1[2] << 4;
$gray4 = $Gray1[3] << 6;

// 将4个像素打包到一个字节中,用于CIP图像
$grey = $gray1 | $gray2 | $gray3 | $gray4;

// CIP图像数据以十六进制发送,strtoupper实际上并不需要。
$code = strtoupper(dechex($grey));

// 我快速修复了填充单个十六进制值的代码
if (strlen($code)==1) $code = "0".$code;
echo $code;

}

}
echo "</Data>";
echo "<Title>$myvar</Title> ";
echo "<Prompt>$city</Prompt> ";
echo "</CiscoIPPhoneImage>";
exit;
1
switch251 at netcourrier dot com
20年前
除了code_couturier之外:他的代码会生成蓝色图片,因为他用来设置像素颜色的值(代码不完整:我最初以为应该是$gray)在0到255之间,对应于蓝色级别。

要将图片转换为灰度,请使用以下代码

<?php
// 替换为您的文件
$originalFileName = "colorPicture.jpg";
$destinationFileName = "bwPicture.jpg";

// 创建原始图像的副本
// 支持jpg图像
// 可以随意修改以适应其他格式 ;)
$fullPath = explode(".",$originalFileName);
$lastIndex = sizeof($fullPath) - 1;
$extension = $fullPath[$lastIndex];
if (
preg_match("/jpg|jpeg|JPG|JPEG/", $extension)){
$sourceImage = imagecreatefromjpeg($originalFileName);
}

// 获取图像尺寸
$img_width = imageSX($sourceImage);
$img_height = imageSY($sourceImage);

// 转换为灰度
// 注意:这不会影响您的原始图像,除非
// originalFileName 和 destinationFileName 相同
for ($y = 0; $y <$img_height; $y++) {
for (
$x = 0; $x <$img_width; $x++) {
$rgb = imagecolorat($sourceImage, $x, $y);
$red = ($rgb >> 16) & 0xFF;
$green = ($rgb >> 8) & 0xFF;
$blue = $rgb & 0xFF;

$gray = round(.299*$red + .587*$green + .114*$blue);

// 将灰度值左移
$grayR = $gray << 16; // R: 红色
$grayG = $gray << 8; // G: 绿色
$grayB = $gray; // B: 蓝色

// 使用或运算计算灰度值
$grayColor = $grayR | $grayG | $grayB;

// 设置像素颜色
imagesetpixel ($sourceImage, $x, $y, $grayColor);
imagecolorallocate ($sourceImage, $gray, $gray, $gray);
}
}

// 将像素值复制到新文件缓冲区
$destinationImage = ImageCreateTrueColor($img_width, $img_height);
imagecopy($destinationImage, $sourceImage, 0, 0, 0, 0, $img_width, $img_height);

// 在磁盘上创建文件
imagejpeg($destinationImage, $destinationFileName);

// 销毁临时图像缓冲区
imagedestroy($destinationImage);
imagedestroy($sourceImage);
?>

复制粘贴,替换顶部的文件名,然后就可以使用了(图片文件必须与该脚本位于同一文件夹中。如果不是,则需要自己进行文件管理)。
1
mail at laeubi dot de
21年前
此函数在我的trucolerimages上无法正常工作(尚未尝试其他类型),它只是生成部分灰度图像,并且某些颜色会出错。
我在这里找到了一个解决方法
http://www.phpbuilder.com/columns/cash20030526.php3?page=2

[引用]
GD库下的高级图像编辑
着色
图像着色相当容易。最简单的着色方法很容易理解。创建一个相同尺寸的图像,并用您想要更改的颜色填充该图像。然后将这个新图像放置在旧图像的顶部,使其呈现着色外观。



<?php
function imagecolorize(&$im,&$col,$pct) {
// 获取图像宽度
$im_w = imagesx($im);
// 获取图像高度
$im_h = imagesy($im);
// 使用颜色设置一个像素,以便我们可以轻松获取它
$setpixel = imagesetpixel($im,$im_w,0,$col);
// 获取颜色
$index = imagecolorat($im,$im_w,0);
// 在索引中查找颜色
$rgb = imagecolorsforindex($im,$index);
// 获取红色值
$r = $rgb["red"];
// 获取绿色值
$g = $rgb["green"];
// 获取蓝色值
$b = $rgb["blue"];
// 创建叠加层
$layover = imagecreate($im_w,$im_h);
// 在此图像上分配颜色
$color = imagecolorallocate($layover,$r,$g,$b);
// 使用新颜色填充图像(实际上不需要)
$fill = imagefill($layover,0,0,$color);
// 将叠加层合并到旧图像的顶部
$merge = imagecopymerge($im,$layover,0,0,0,0,$im_w,$im_h,$pct);
imagedestroy($layover); // 销毁叠加层
}
?>

如果我们使用蓝色叠加层 RGB(0,0,255),我们将得到此结果
[/quote]

如果你使用黑色或灰色,它并不完美,但总比没有好;)
0
szamil at ginf dot pl
17 年前
我稍微修改了一下 switch251 的代码,现在我们有了棕褐色效果
<?php
// 替换为你的文件
$originalFileName = $filename;
$destinationFileName = "2".$filename;

// 创建原始图像的副本
// 适用于 jpg 图像
// 随意调整以适应其他格式 ;)
$fullPath = explode(".",$originalFileName);
$lastIndex = sizeof($fullPath) - 1;
$extension = $fullPath[$lastIndex];
if (
preg_match("/jpg|jpeg|JPG|JPEG/", $extension))
{
$sourceImage = imagecreatefromjpeg($originalFileName);
}

// 获取图像尺寸
$img_width = imageSX($sourceImage);
$img_height = imageSY($sourceImage);

// 转换为灰度
// 注意:这不会影响你的原始图像,除非
// originalFileName 和 destinationFileName 相同
for ($y = 0; $y <$img_height; $y++)
{
for (
$x = 0; $x <$img_width; $x++)
{
$rgb = imagecolorat($sourceImage, $x, $y);
$red = ($rgb >> 16) & 0xFF;
$green = ($rgb >> 8) & 0xFF;
$blue = $rgb & 0xFF;

// 棕褐色
$red2 = min($red*.393 + $green*.769 + $blue*.189,255);
$green2 = min($red*.349 + $green*.686 + $blue*.168,255);
$blue2 = min($red*.272 + $green*.534 + $blue*.131,255);
// 将灰度级向左移动

$grayR = $red2 << 16; // R: 红色
$grayG = $green2 << 8 ; // G: 绿色
$grayB = $blue2; // B: 蓝色

// OR 操作计算灰度值
$grayColor = $grayR | $grayG | $grayB;


// 设置像素颜色
imagesetpixel ($sourceImage, $x, $y, $grayColor);
imagecolorallocate ($sourceImage, $gray, $gray, $gray);
}
}

// 将像素值复制到新文件缓冲区
$destinationImage = ImageCreateTrueColor($img_width, $img_height);
imagecopy($destinationImage, $sourceImage, 0, 0, 0, 0, $img_width, $img_height);

// 在磁盘上创建文件
imagejpeg($destinationImage, $destinationFileName);

// 销毁临时图像缓冲区
imagedestroy($destinationImage);
imagedestroy($sourceImage);
?>
0
annonymous at example dot com
20年前
除了 code_couturier 之外 - 尝试使用此公式计算他“更精确”方式中的灰度值(亮度)

$gray = round(.299*$red + .587*$green + .114*$blue);
0
code_couturier at graffiti dot net
21年前
# 生成灰度图像的非常快速方法 -
# 来自真彩色图像

#...

# --- 快速灰度图像
for ($y = 0; $y <$img_height; $y++) {
for ($x = 0; $x <$img_width; $x++) {

# 在这里,我们提取绿色
# 来自 x,y 处的像素,用作灰度值
$gray = (ImageColorAt($image, $x, $y) >> 8) & 0xFF;

# 更精确的方法是
# $rgb = ImageColorAt($image, $x, $y);
# $red = ($rgb >> 16) & 0xFF;
# $green = (trgb >> 8) & 0xFF;
# $blue = $rgb & 0xFF;
# $gray = (int)(($red+$green+$blue)/4);

# 这里我们设置新的像素/颜色
imagesetpixel ($image, $x, $y,
ImageColorAllocate ($image, $gray,$gray,$gray));
}
}

# ...
-1
anonymous at domain dot com
15 年前
灰度转换是使用 imagefilter() 内置的。

<?php
/* 其他代码 */

$image = imagecreatefromjpeg('some.jpg');
imagefilter($image, IMG_FILTER_GRAYSCALE);

/* 其他代码(例如保存) */

imagedestroy($image);

/* 其他代码 */
?>

您可以通过以下方式创建棕褐色效果

<?php
/* 其他代码 */

$image = imagecreatefromjpeg('some.jpg');
imagefilter($image, IMG_FILTER_GRAYSCALE);
imagefilter($image, IMG_FILTER_COLORIZE, 112, 66, 20);
//维基百科关于棕褐色的RGB定义

/* 其他代码(例如保存) */

imagedestroy($image);

/* 其他代码 */
?>
To Top