图像处理和 GD

简介

PHP 并不仅限于创建 HTML 输出, 它也可以创建和处理包括 GIFPNGJPEGWBMP 以及 XPM 在内的多种格式的图像。 更加方便的是,PHP 可以直接将图像数据流输出到浏览器。 要想在 PHP 中使用图像处理功能,你需要连带 GD 库一起来编译 PHP。 GD 库和 PHP 可能需要其他的库, 这取决于你要处理的图像格式。

你可以使用 PHP 中的图像函数来获取下列格式图像的大小: JPEGGIFPNGSWFTIFFJPEG2000

如果联合 exif 扩展 一起使用, 你可以操作存储在 JPEGTIFF 图像文件头部的信息, 这样就就可以获取数码相机所产生的元数据。 exif 相关的函数不需要 GD 库亦可使用。

注意: 关于如何扩展图像处理能力,例如读取、写入以及修改, 请参考“需求”一节。 要想读取数码相机拍摄的图片的元数据, 你需要上面提到的 exif 扩展

注意: getimagesize() 函数不需要 GD 扩展库。

警告

由于绑定的 GD 库使用 Zend 内存管理机制来分配内存, 所以所使用的内存大小不受 memory_limit 配置参数限制。

GD 库支持多种图像格式, 下标所列的是 GD 所支持的格式,请注意备图像格式对应的读取/写入支持的可用性。

GD 所支持的格式
格式 支持读取 支持写入 备注
JPEG true true  
PNG true true  
GIF true true  
XBM true true  
XPM true false  
WBMP true true  
WebP true true  
BMP true true 从 PHP 7.2.0 开始支持

很遗憾的是,虽然上表中显示大部分图像格式都是支持读取和写入的, 但是不代表你的 PHP 环境在编译的时候是支持这些操作的。 要想检测 GD 库所支持的格式,请使用 gd_info() 函数, 更多信息请参考 “安装” 一章。

添加备注

用户贡献的备注 5 notes

up
5
mail at ecross dot nl
15 years ago
hello there,
i made a function to create a gradient image.

description:
gradient(int image_width, int image_height, 
int start_red, int start_green, int start_blue, 
int end_red, int end_green, int end_blue, 
bool vertical)

function:
<?php
function gradient($image_width, $image_height,$c1_r, $c1_g, $c1_b, $c2_r, $c2_g, $c2_b, $vertical=false)
{
// first: lets type cast;
$image_width = (integer)$image_width;
$image_height = (integer)$image_height;
$c1_r = (integer)$c1_r;
$c1_g = (integer)$c1_g;
$c1_b = (integer)$c1_b;
$c2_r = (integer)$c2_r;
$c2_g = (integer)$c2_g;
$c2_b = (integer)$c2_b;
$vertical = (bool)$vertical;

// create a image
$image  = imagecreatetruecolor($image_width, $image_height); 

// make the gradient
for($i=0; $i<$image_height; $i++) 
{ 
$color_r = floor($i * ($c2_r-$c1_r) / $image_height)+$c1_r;
$color_g = floor($i * ($c2_g-$c1_g) / $image_height)+$c1_g;
$color_b = floor($i * ($c2_b-$c1_b) / $image_height)+$c1_b;

$color = ImageColorAllocate($image, $color_r, $color_g, $color_b);
imageline($image, 0, $i, $image_width, $i, $color);
} 

# Prints out all the figures and picture and frees memory 
header('Content-type: image/png'); 

if($vertical){$image = imagerotate($image, 90, 0);}
ImagePNG($image); 
imagedestroy($image); 
}
?>
up
3
kurdtpage at gmail dot com
14 years ago
When using GD, please make sure of the following things:

1. The file that is used to manipulate images is saved as ANSI format and not UTF-8
2. There is no space in front of the opening tag <?php
up
1
Thomas
17 years ago
You know, maybe this goes without saying, but I thought I would drop a note in here.  When developing code to resize images, it is best not to use GD.  When using the current GD methodologies, you are reading content from an image and manipulating it.  By then writing that content to a brand new file, you are losing the EXIF data.

For purposes when you want to retain EXIF data, it is recommended that you compile in and use the PECL Imagick extension.  It has great resizing methods built right in and the EXIF data is retained.
up
-1
herbert dot walde at googlemail dot com
14 years ago
In case your script is using output-buffering-functions somewhere, then you have to clear the buffer first ( with ob_clear() ), before outputting an image with a function like imagepng(). 

And you should make sure that no buffer will get send after outputing an image by using the ob_end_flush()-function.

Furthermore you should check if a buffer has already been flushed somewhere before. This can be done using the headers_sent()-function.

Here is the full solution:

<?php
if(headers_sent()){
    die('Headers have been send somewhere within my script');
}

ob_clean(); //Clears the buffer

header('Content-type: image/png');
imagepng($img, NULL, 0,  NULL);

ob_end_flush(); //Now we send the header and image plus we make sure that nothing will get send from now on (including possible shutdown-functions and __destruct()-methods) till the end of page-execution
?>
up
-2
code at ashleyhunt dot co dot uk
17 years ago
I have been looking to send the output from GD to a text string without proxying via a file or to a browser.

I have come up with a solution.

This code buffers the output between the ob_start() and ob_end() functions into ob_get_contents()

See the example below

<?php
// Create a test source image for this example
$im = imagecreatetruecolor(300, 50);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5,  'A Simple Text String', $text_color);

// start buffering
ob_start();
// output jpeg (or any other chosen) format & quality
imagejpeg($im, NULL, 85);
// capture output to string
$contents = ob_get_contents();
// end capture
ob_end_clean();

// be tidy; free up memory
imagedestroy($im);

// lastly (for the example) we are writing the string to a file
$fh = fopen("./temp/img.jpg", "a+" );
    fwrite( $fh, $contents );
fclose( $fh );
?> 

Enjoy!
Ashley
To Top