GD and Image 函数
在线手册:中文  英文

imagecopymergegray

(PHP 4 >= 4.0.6, PHP 5)

imagecopymergegray用灰度拷贝并合并图像的一部分

说明

bool imagecopymergegray ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h , int $pct )

src_im 图像中坐标从 src_xsrc_y 开始,宽度为 src_w,高度为 src_h 的一部分拷贝到 dst_im 图像中坐标为 dst_xdst_y 的位置上。两图像将根据 pct 来决定合并程度,其值范围从 0 到 100。当 pct = 0 时,实际上什么也没做,当为 100 时本函数和 imagecopy() 完全一样。

本函数和 imagecopymerge() 完全一样只除了合并时通过在拷贝操作前将目标像素转换为灰度级来保留了原色度。

Note:

本函数添加于 PHP 4.0.6。


GD and Image 函数
在线手册:中文  英文

用户评论:

anonymous at domain dot com (2009-10-16 15:54:04)

grayscale conversion is built-in with imagefilter(). 

<?php
     
/* other code */

     
$image imagecreatefromjpeg('some.jpg');
     
imagefilter($imageIMG_FILTER_GRAYSCALE);

     
/* other code (ie save) */

     
imagedestroy($image);

     
/* other code */
?>

you could create the sepia effect by the following:

<?php
     
/* other code */

     
$image imagecreatefromjpeg('some.jpg');
     
imagefilter($imageIMG_FILTER_GRAYSCALE);
     
imagefilter($imageIMG_FILTER_COLORIZE1126620);
     
//Wikipedia RGB definition of sepia

     /* other code (ie save) */

     
imagedestroy($image);

     
/* other code */
?>

amezghal at msn dot com (2008-05-09 17:59:41)

gray effect :)
<?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_img000);
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);
   }
}
?>

szamil at ginf dot pl (2007-04-15 14:17:59)

I've changed a little switch251's code and here we have sephia effect
<?php
   
// replace with your files
    
$originalFileName    $filename;
    
$destinationFileName "2".$filename;
    
    
// create a copy of the original image
    // works with jpg images
    // fell free to adapt to other formats ;)
    
$fullPath explode(".",$originalFileName);
    
$lastIndex sizeof($fullPath) - 1;
    
$extension $fullPath[$lastIndex];
    if (
preg_match("/jpg|jpeg|JPG|JPEG/"$extension))
    {
        
$sourceImage imagecreatefromjpeg($originalFileName);
    }

    
// get image dimensions
    
$img_width  imageSX($sourceImage);
    
$img_height imageSY($sourceImage);

    
// convert to grayscale
    // note: this will NOT affect your original image, unless
    // originalFileName and destinationFileName are the same
    
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;

          
//sephia
            
$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);
            
// shift gray level to the left
            
            
$grayR $red2 << 16;   // R: red
            
$grayG $green2 << ;    // G: green
            
$grayB $blue2;         // B: blue
            
            // OR operation to compute gray value
            
$grayColor $grayR $grayG $grayB;

            
            
// set the pixel color
            
imagesetpixel ($sourceImage$x$y$grayColor);
            
imagecolorallocate ($sourceImage$gray$gray$gray);
        }
    }

    
// copy pixel values to new file buffer
    
$destinationImage ImageCreateTrueColor($img_width$img_height);
    
imagecopy($destinationImage$sourceImage0000$img_width$img_height);

    
// create file on disk
    
imagejpeg($destinationImage$destinationFileName);
    
    
// destroy temp image buffers
    
imagedestroy($destinationImage);    
    
imagedestroy($sourceImage);
?>

Mark Barba (2005-08-15 12:31:48)

// Using the same code I found here on php.net,
// I was able to figure out how to convert GIF (or any other
// format GD supports) to CIP format. CIP is the image
// format for Cisco IP Phones... 7905/7940 and 7960
// models... Hope someone finds this useful and make it
// better...
/////// GIF2CIP PHP code ///////
// Convert image in memory to grayscale
$img_width = imageSX($im2);
$img_height = imageSY($im2);
// convert to grayscale
// note: this will NOT affect your original image, unless
// originalFileName and destinationFileName are the same
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);

// shift gray level to the left
$grayR = $gray << 16; // R: red
$grayG = $gray << 8; // G: green
$grayB = $gray; // B: blue

// OR operation to compute gray value
$grayColor = $grayR | $grayG | $grayB;
// set the pixel color
imagesetpixel ($im2, $x, $y, $grayColor);
imagecolorallocate ($im2, $gray, $gray, $gray);
}
}
/////////////////////////////////////////////////////////
// Modifies palette to only 4-colors (CIP Images on 7905/7940 & 7960 is 2-bit color)
ImageTrueColorToPalette2($im2,FALSE,4);
// Basic header for CIP Image files...
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>";
// get image dimensions (almost same code as above)
$img_width = imageSX($im2);
$img_height = imageSY($im2);
// convert to grayscale
// note: this will NOT affect your original image, unless
// originalFileName and destinationFileName are the same
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);
// I came up with this translation on my own
// Some smart person is bound to perfect it
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;

// Pack 4 pixels into a single byte for CIP images
$grey = $gray1 | $gray2 | $gray3 | $gray4;
// CIP image data is sent in HEX, strtoupper is not really needed.
$code = strtoupper(dechex($grey));
// My quick fix to padding single HEX values
if (strlen($code)==1) $code = "0".$code;
echo $code;

}
}
echo "</Data>";
echo "<Title>$myvar</Title> ";
echo "<Prompt>$city</Prompt> ";
echo "</CiscoIPPhoneImage>";
exit;

switch251 at netcourrier dot com (2004-04-15 07:18:56)

In addition to code_couturier too: his code will produce blue pictures, because the value he uses to set the pixel color (the code is incomplete: I first thought it should be $gray) is between 0 and 255, which corresponds to blue levels.

To convert the picture to grayscale, use the following code:

<?php
    
// replace with your files
    
$originalFileName    "colorPicture.jpg";
    
$destinationFileName "bwPicture.jpg";
    
    
// create a copy of the original image
    // works with jpg images
    // fell free to adapt to other formats ;)
    
$fullPath explode(".",$originalFileName);
    
$lastIndex sizeof($fullPath) - 1;
    
$extension $fullPath[$lastIndex];
    if (
preg_match("/jpg|jpeg|JPG|JPEG/"$extension)){
        
$sourceImage imagecreatefromjpeg($originalFileName);
    }

    
// get image dimensions
    
$img_width  imageSX($sourceImage);
    
$img_height imageSY($sourceImage);

    
// convert to grayscale
    // note: this will NOT affect your original image, unless
    // originalFileName and destinationFileName are the same
    
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);
            
            
// shift gray level to the left
            
$grayR $gray << 16;   // R: red
            
$grayG $gray << 8;    // G: green
            
$grayB $gray;         // B: blue
            
            // OR operation to compute gray value
            
$grayColor $grayR $grayG $grayB;

            
// set the pixel color
            
imagesetpixel ($sourceImage$x$y$grayColor);
            
imagecolorallocate ($sourceImage$gray$gray$gray);
        }
    }

    
// copy pixel values to new file buffer
    
$destinationImage ImageCreateTrueColor($img_width$img_height);
    
imagecopy($destinationImage$sourceImage0000$img_width$img_height);

    
// create file on disk
    
imagejpeg($destinationImage$destinationFileName);
    
    
// destroy temp image buffers
    
imagedestroy($destinationImage);    
    
imagedestroy($sourceImage);
?>

Copy-paste, replace the file names on the top and there you go (picture files must be in same folder as this script. If not, you will have to do your own file management).

annonymous at example dot com (2004-02-15 16:25:45)

in addition to code_couturier - try this formula to calculate gray-value (luminance) in his "more exact" way:
$gray = round(.299*$red + .587*$green + .114*$blue);

code_couturier at graffiti dot net (2003-10-18 00:08:23)

# very fast way to generate a grayscal-
# image from a true color image
#...
# --- quick grayscale image
for ($y = 0; $y <$img_height; $y++) {
for ($x = 0; $x <$img_width; $x++) {
# here we extract the green from
# the pixel at x,y , to use it as gray value
$gray = (ImageColorAt($image, $x, $y) >> 8) & 0xFF;
# a more exact way would be this:
# $rgb = ImageColorAt($image, $x, $y);
# $red = ($rgb >> 16) & 0xFF;
# $green = (trgb >> 8) & 0xFF;
# $blue = $rgb & 0xFF;
# $gray = (int)(($red+$green+$blue)/4);
# and here we set the new pixel/color
imagesetpixel ($image, $x, $y,
ImageColorAllocate ($image, $gray,$gray,$gray));
}
}

# ...

mail at laeubi dot de (2003-10-09 00:45:22)

This function don't work properly for me on trucolerimages (have not tried yet for other types) it jsut produce a part-grayscale image, and some color get mesed up.
I found a workaround here:
http://www.phpbuilder.com/columns/cash20030526.php3?page=2

[quote]
Advanced Image Editing Under the GD Library
Colorizing
Colorizing images is fairly easy to do. The easiest way to colorize an image is fairly simple to grasp. Create an image of the same dimensions and fill that image with the color you want to change it to. This new image is then placed on top of the older image, giving it a colorized look.

<?php 
function imagecolorize(&$im,&$col,$pct) { 
    
// Get the image's width 
    
$im_w imagesx($im);  
    
// Get the image's height 
    
$im_h imagesy($im);  
    
// Set a pixel with the color, so we can get it easily 
    
$setpixel imagesetpixel($im,$im_w,0,$col);  
    
// Get the color 
    
$index imagecolorat($im,$im_w,0);  
    
// Find the color in the index 
    
$rgb imagecolorsforindex($im,$index);  
    
// Get the red value 
    
$r $rgb["red"]; 
    
// Get the green value 
    
$g $rgb["green"];  
    
// Get the blue value 
    
$b $rgb["blue"];  
    
// Create the layover 
    
$layover imagecreate($im_w,$im_h);  
    
// Allocate the color on this image 
    
$color imagecolorallocate($layover,$r,$g,$b);  
    
// Fill the image with the new color (this really isn't needed) 
    
$fill imagefill($layover,0,0,$color);  
    
// Merge the layover on top of the older image 
    
$merge imagecopymerge($im,$layover,0,0,0,0,$im_w,$im_h,$pct); 
    
imagedestroy($layover); // Destroy the layover 

?> 

If we use a blue layover RGB(0,0,255), we get this result:
[/quote]

if you use black or gray, its not perfekt, but better than nothing ;)

易百教程