imagepng

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

imagepng将 PNG 图像输出到浏览器或文件

说明

imagepng(
    GdImage $image,
    resource|string|null $file = null,
    int $quality = -1,
    int $filters = -1
): bool

从给定的 image 输出或保存 PNG 图像。

参数

image

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

file

保存文件的路径或打开的流资源(在此函数返回后会自动关闭)。如果未设置或为 null,则会直接输出原始图像流。

注意:

如果未使用 qualityfilters 参数,则 null 无效。

quality

压缩级别:从 0(无压缩)到 9。默认值(-1)使用 zlib 压缩默认值。有关更多信息,请参阅 » zlib 手册

filters

允许减少 PNG 文件大小。它是一个位掩码字段,可以设置为 PNG_FILTER_XXX 常量的任何组合。PNG_NO_FILTERPNG_ALL_FILTERS 也可用于分别禁用或激活所有过滤器。默认值(-1)禁用过滤。

注意

filters 参数会被系统 libgd 忽略。

返回值

成功返回 true,失败返回 false

注意

但是,如果 libgd 无法输出图像,则此函数将返回 true

变更日志

版本 说明
8.0.0 image 现在期望一个 GdImage 实例;以前,期望一个有效的 gd resource

示例

<?php
$im
= imagecreatefrompng("test.png");

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

imagepng($im);
imagedestroy($im);
?>

参见

添加注释

用户贡献的注释 35 个注释

49
matteosistisette at gmail dot com
12 年前
压缩参数的名称“quality”非常具有误导性,因为 png 压缩始终是无损的。权衡是速度和文件大小,它不会影响质量。

我在 stackoverflow 上找到了一些内容;我还没有检查它,但如果它是正确的,它应该在文档中包含。

---
来自 php 源代码 (gd.h)

/* 2.0.12: 压缩级别:0-9 或 -1,其中 0 表示完全不压缩,
* 1 最快,但会生成更大的文件,9 提供最佳
* 压缩(最小的文件),但压缩需要很长时间,并且
* -1 选择编译到 zlib 库中的默认值。
*/
结论:根据 Zlib 手册 (http://www.zlib.net/manual.html),默认压缩级别设置为 6。
---

关于将 jpeg 的 0-99 质量范围重新缩放到 png 的 0-9 范围的建议,请注意,对于 jpeg,99 是最小压缩(最高质量),而对于 png,9 是最大压缩(质量不会改变)。
41
匿名
21 年前
“提示:与直接将结果输出到浏览器的任何其他内容一样,您可以使用输出控制函数 (https://php.net/manual/en/ref.outcontrol.php) 来捕获此函数的输出,并将其保存在字符串中(例如)。”

ob_start();
imagepng($image);
$image_data = ob_get_contents();
ob_end_clean();

现在,您可以将 $image_data 保存到数据库中,例如,而不是先将其写入文件,然后再从文件中读取数据。只是不要忘记使用 mysql_escape_string...
4
mail at stefanbechtold dot de
21 年前
对于所有希望用户在填写个人资料时上传图像而不破坏固定设计的人来说,以下方法应该是一个很好的解决方法。

此文件从 $imagepath 打开一个图片,并将其作为有效图片返回,嵌入到:<img src="file.php?image=123.jpg[?maxX=200&maxY=150]"> 中([] 中为可选)。

但此文件不仅仅是这些。它还为小于最大尺寸的文件添加黑色边框,因此在图像太高时会在左侧和右侧添加边框 :-)

如果有版权声明的需要,此脚本也会帮助您。您可以将各种文本放在 $copyright 中。文本长度应与 $maxX 和 $maxY 相关。

好吧,脚本还有其他功能,您只需尝试一下,玩得开心 :-)

再见

<?php

# 如果没有给出,则使用标准高度和宽度
if(!isset($maxX)) $maxX = 100;
if(!isset(
$maxY)) $maxY = 75;

# 颜色和文本值
$picBG = "0,0,0"; # RGB 值!
$picFG = "104,104,104"; # RGB 值!
$copyright = "stefan bechtold";
$font = 1;

# 最小和最大缩放
$minZoom = 1; # 相对于原始图像的百分比(不等于 0)
$maxZoom = 200; # 相对于原始图像的百分比(不等于 0)

# 路径
$imgpath = "userimages/"; # 以 "/" 结尾!
$nopicurl = "../images/nopic.jpg"; # 从 $imagepath 开始!!!
$nofileurl = "../images/nofile.jpg"; # 从 $imagepath 开始!!!

if(!isset($image) || empty($image))
$imageurl = $imgpath . $nopicurl;
elseif(!
file_exists($imgpath . trim($image)))
$imageurl = $imgpath . $nofileurl;
else
$imageurl = $imgpath . trim($image);

# 读取图像
$image = getImageSize($imageurl, $info); # $info,仅用于处理早期 PHP 版本的问题...
switch($image[2]) {
case
1:
# GIF 图像
$timg = imageCreateFromGIF($imageurl);
break;
case
2:
# JPEG 图像
$timg = imageCreateFromJPEG($imageurl);
break;
case
3:
# PNG 图像
$timg = imageCreateFromPNG($imageurl);
break;
}

# 读取图像尺寸
$imgX = $image[0];
$imgY = $image[1];

# 计算缩放因子
$_X = $imgX/$maxX * 100;
$_Y = $imgY/$maxY * 100;

# 选择正确的缩放因子,以便图像始终保持在给定的格式中
# 无论它是更高还是更宽,反之亦然
if((100-$_X) < (100-$_Y)) $_K = $_X;
else
$_K = $_Y;

# 缩放检查到原始图像
if($_K > 10000/$minZoom) $_K = 10000/$minZoom;
if(
$_K < 10000/$maxZoom) $_K = 10000/$maxZoom;

# 计算新的图像尺寸
$newX = $imgX/$_K * 100;
$newY = $imgY/$_K * 100;

# 设置图像的起始位置
# 始终居中
$posX = ($maxX-$newX) / 2;
$posY = ($maxY-$newY) / 2;

# 创建具有给定尺寸的新图像
$imgh = imageCreateTrueColor($maxX, $maxY);

# 设置颜色
$cols = explode(",", $picBG);
$bgcol = imageColorallocate($imgh, trim($cols[0]), trim($cols[1]), trim($cols[2]));
$cols = explode(",", $picFG);
$fgcol = imageColorallocate($imgh, trim($cols[0]), trim($cols[1]), trim($cols[2]));

# 填充背景
imageFill($imgh, 0, 0, $bgcol);

# 创建图像的小副本
imageCopyResampled($imgh, $timg, $posX, $posY, 0, 0, $newX, $newY, $image[0], $image[1]);

# 编写版权信息
imageStringUp($imgh, $font, $maxX-9, $maxY-3, $copyright, $fgcol);

# 输出
switch($image[2]) {
case
1:
# GIF 图像
header("Content-type: image/gif");
imageGIF($imgh);
case
2:
# JPEG 图像
header("Content-type: image/jpeg");
imageJPEG($imgh);
case
3:
# PNG 图像
header("Content-type: image/png");
imagePNG($imgh);
}

# 清理缓存
imageDestroy($timg);
imageDestroy($imgh);

?>
15
r.lomas at infonie.fr
14 年前
我刚刚在一個非常愚蠢的问题上浪费了 4 个小时。我本地服务器上的图片不知何故坏了,因此无法在浏览器中显示。在经过一番搜索和测试后,包括在我的电脑上重新安装 Apache 好几次,我发现问题出在一个包含的文件上。
问题不在于空格,而是我包含的其中一个文件开头有一个 UTF BOM 编码字符...
所以要小心你包含的文件!
确保它们没有以 UTF 或其他方式以 UTF 编码,但不包含 BOM。
希望这能为他人节省时间。
13
luxian.m [at] gmail [dot] com
15 年前
如果你想打开一张带有 alpha 混合的 png 图片,你需要执行类似以下的操作

<?php
$file
= 'semitransparent.png'; // png 图片的路径
$img = imagecreatefrompng($file); // 打开图片
imagealphablending($img, true); // 打开 alpha 混合
imagesavealpha($img, true); // 保存 alpha 混合设置(重要)
?>

我花了将近一天时间才找出为什么 alpha 混合不起作用。我希望这对其他人也有用 :)
10
geompse at gmail dot com
12 年前
使用变量作为文件名时要小心。
PHP 在升级到 PHP5.4 之后,$filename 的行为会有所不同:PHP5.3 将以与 $filename=NULL 相同的方式使用 $filename=''(例如,不会发出警告)
<?php
$im
= imagecreatetruecolor(10,10);
imagepng($im,'',9); # 警告:imagepng(): 文件名不能为空
imagepng($im,NULL,9); # 按预期工作
imagedestroy($im);
?>
2
johnbeech at mkv25.net
21 年前
PNG 文件已经是压缩的。它们使用无损压缩算法。如果您使用的是高色图像,压缩只能起到一定作用。对于低色图像(16 或 256 色),压缩效果要好得多。

在发送到浏览器之前尝试进一步压缩图像毫无意义。
10
mhorne69 at gmail dot com
13 年前
如果您基于帖子数据动态生成图像,并且不想将其保存到服务器,则将其发送以显示可能会导致问题,因为当用户尝试保存它时,浏览器将再次从服务器请求它(导致任何帖子数据丢失,并可能导致损坏的 png)。

解决此问题的最简单方法是使用内容处置标头强制其下载,例如

<?php
header
('Content-Disposition: Attachment;filename=image.png');
header('Content-type: image/png');
?>
5
Chris F
9 年前
我很好奇质量、处理时间和结果图像大小之间的关系,所以我创建了这个小基准来测试它(使用的图像最初是 RGB_24bits_palette_R85.png,在维基百科上找到)。结果在底部。
<?php
$sizes
= ['32', '64', '128', '256', '512', '1024', '2048'];

foreach (
$sizes as $size) {
echo
"\nSize: {$size}x{$size}px:\n";

$image = imagecreatefrompng("images/test{$size}.png");
for (
$quality = 0; $quality < 10; $quality++) {
ob_start();

$start = microtime(true);
imagepng($image, null, $quality);
$elapsed = microtime(true) - $start;

$blob = ob_get_contents();
ob_end_clean();

$blobSize = strlen($blob);
echo
"quality: $quality, size: $blobSize, elapsed: $elapsed\n";
}

imagedestroy($image);
}

// 结果(为简洁起见省略了一些):

// Size: 32x32px:
// quality: 0, size: 3172, elapsed: 0.00013399124145508
// quality: 1, size: 266, elapsed: 9.4890594482422E-5
// quality: 2, size: 264, elapsed: 7.7009201049805E-5
// quality: 3, size: 223, elapsed: 7.4863433837891E-5
// quality: 4, size: 225, elapsed: 8.5830688476562E-5
// quality: 5, size: 209, elapsed: 8.5115432739258E-5
// quality: 6, size: 208, elapsed: 9.608268737793E-5
// quality: 7, size: 205, elapsed: 0.0001060962677002
// quality: 8, size: 186, elapsed: 0.00015091896057129
// quality: 9, size: 181, elapsed: 0.00022006034851074

// Size: 128x128px:
// quality: 0, size: 49425, elapsed: 0.0010969638824463
// quality: 1, size: 976, elapsed: 0.00091886520385742
// quality: 2, size: 938, elapsed: 0.00088310241699219
// quality: 3, size: 925, elapsed: 0.00087594985961914
// quality: 4, size: 608, elapsed: 0.0009760856628418
// quality: 5, size: 607, elapsed: 0.00098395347595215
// quality: 6, size: 601, elapsed: 0.0010099411010742
// quality: 7, size: 602, elapsed: 0.001086950302124
// quality: 8, size: 521, elapsed: 0.001910924911499
// quality: 9, size: 491, elapsed: 0.0029060840606689

// Size: 512x512px:
// quality: 0, size: 788279, elapsed: 0.012928009033203
// quality: 1, size: 12467, elapsed: 0.013065099716187
// quality: 2, size: 11885, elapsed: 0.013008117675781
// quality: 3, size: 11190, elapsed: 0.013030052185059
// quality: 4, size: 7311, elapsed: 0.016619920730591
// quality: 5, size: 6994, elapsed: 0.016351222991943
// quality: 6, size: 6475, elapsed: 0.016234159469604
// quality: 7, size: 6432, elapsed: 0.016525983810425
// quality: 8, size: 6094, elapsed: 0.022937774658203
// quality: 9, size: 5649, elapsed: 0.065664052963257

// Size: 2048x2048px:
// quality: 0, size: 12605375, elapsed: 0.20983290672302
// quality: 1, size: 451735, elapsed: 0.19678711891174
// quality: 2, size: 409375, elapsed: 0.19415307044983
// quality: 3, size: 366404, elapsed: 0.20460414886475
// quality: 4, size: 312538, elapsed: 0.22785305976868
// quality: 5, size: 281671, elapsed: 0.23320484161377
// quality: 6, size: 244248, elapsed: 0.28935289382935
// quality: 7, size: 238310, elapsed: 0.33481192588806
// quality: 8, size: 217038, elapsed: 0.71698379516602
// quality: 9, size: 208881, elapsed: 1.858146905899
?>
1
bgd1977 at hotmail dot com
22 年前
我在以下配置中遇到过段错误和总线错误:FreeBSD4.4、Apache 1.3.26、PHP 4.2.2、GD-1.8.4、PDFlib 4.0.1。当调用 imagepng 函数时,apache 进程崩溃,但在调用 imagejpg 函数或 imagecreatefrompng 时没有崩溃。

经过几个小时的浪费(很多),我尝试重新编译 gd、libpng、php、libjpeg 等等,我找到了以下建议
http://bugs.php.net/bug.php?id=16841

所以问题不在于 png 库,而在于 PDFlib。尽管所有线索都指向 png 问题...所以我只是升级到 PDFlib 4.0.3(没有任何特殊的配置参数;--with-libpng 根本不起作用),重新编译 PHP,现在一切正常(imagepng、pdf 创建等)。

希望这有帮助,
bogdan
2
php dot net at phor dot net
10 年前
如果您直接输出 PNG 以响应客户端请求,则必须检查您的 Web 服务器配置。

某些客户端可能会使用 <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">accept 标头</a> 来请求您的图像,该标头为 image/*。Apache 的默认配置(以及可能的其他服务器)默认情况下将不允许您的脚本响应此请求运行。

Apache 在 http://stackoverflow.com/q/19169337 中进行了特别讨论,但已记录其他服务器也存在此问题。

换句话说,在测试您的应用程序时,不要只使用 Web 浏览器,请考虑手机的浏览器和网络库,这些库可能会发送不同的标头。
3
adrenalin at NOSPAM dot myrealbox dot com
18 年前
尝试调整 256 色 png 图像的大小并将其以 256 色保存,并具有正确的调色板?(如果您以真彩色调色板保存 256 色图像,则结果图像将具有很大的尺寸)。
我花了几个小时尝试各种函数来获得高质量的 256 色 png 图像,但由于调色板的原因,结果图像质量很差。
但是感谢 zmorris at zsculpt dot com 在 imagetruecolortopalette 函数页面上的评论,我想出了如何获得正确图像!

<?php
function resize_png($src,$dst,$dstw,$dsth) {
list(
$width, $height, $type, $attr) = getimagesize($src);
$im = imagecreatefrompng($src);
$tim = imagecreatetruecolor($dstw,$dsth);
imagecopyresampled($tim,$im,0,0,0,0,$dstw,$dsth,$width,$height);
$tim = ImageTrueColorToPalette2($tim,false,255);
imagepng($tim,$dst);
}
//zmorris at zsculpt dot com function, a bit completed
function ImageTrueColorToPalette2($image, $dither, $ncolors) {
$width = imagesx( $image );
$height = imagesy( $image );
$colors_handle = ImageCreateTrueColor( $width, $height );
ImageCopyMerge( $colors_handle, $image, 0, 0, 0, 0, $width, $height, 100 );
ImageTrueColorToPalette( $image, $dither, $ncolors );
ImageColorMatch( $colors_handle, $image );
ImageDestroy($colors_handle);
return
$image;
}
?>

祝您好运!
Namolovan Nicolae,摩尔多瓦
5
alex at gateway-productions dot com
17 年前
Bart 的代码至少在 gd 2 上不起作用

它只返回一个空白的图像,带有 alpha,而不是源图像的调整大小

$im = ImageCreateFromPNG($sourcefile);
$im_dest = imagecreatetruecolor ($forcedwidth, $forcedheight);
imagealphablending($im_dest, false);
imagecopyresampled($im_dest, $im, 0, 0, 0, 0, $wm_width, $wm_height, $forcedwidth, $forcedheight);
imagesavealpha($im_dest, true);
imagepng($im_dest, $destfile);
imagedestroy($img_dest);

ps 你还忘记了图像销毁,而且你在你的帖子中有一个随机变量 imagepng 未定义
2
wietse89 at gmail dot com
14 年前
当你允许多种输出格式(jpg/png)但想使用 1-100 的质量等级(比如 jpg)时,你必须格式化数字

<?php
$pngQuality
= ($quality - 100) / 11.111111;
$pngQuality = round(abs($pngQuality));
imagepng($resource, $path, $pngQuality);
?>
1
neburk0rk at gmail dot com
19 年前
这是我将 PNG 图像存储在 MySQL 数据库中的方法... 你不能直接将 PNG 图像存储在变量中,然后在数据库中解析它,因为如果你试图将它定义为一个变量,它仍然只会输出它...
在我的方法中,我使用了三个函数
"捕获"输出并将其存储在变量中;ob_start(启动输出缓冲)、ob_get_contents(捕获输出)和 ob_end_clean(擦除缓存并结束输出缓冲)

<?php
$imagefile
= "changethistogourimage.gif";

$image = imagecreatefromgif($imagefile);
ob_start();
imagepng($image);
$imagevariable = ob_get_contents();
ob_end_clean();

/*
HERE YOU CAN MESS WITH THE $imagevariable AS YOU LIKE
*/
?>
0
Messerli at messerli dot net
1 年前
// 将图像作为 Base64 数据直接发送到浏览器。
// 服务器上没有文件!没有黑客问题。

ob_start();
imagepng($img);
$ImageData=ob_get_contents();
ob_end_clean();
echo '<img src="data:image/jpg;base64,'.base64_encode($ImageData).'">';
0
klaus at hax dot at
7 年前
显然从 php 5.5 到 5.6 有所变化。

我以前调用 ImagePng($image, '');
显然这在 5.6 中不再起作用,因为它返回:imagepng(): Filename cannot be empty

ImagePng($image, NULL);

似乎可以正常工作。
0
Zane, MegaLab.it
13 年前
我的脚本无法完成:致命错误:允许的内存大小为 XX 字节,已用完(尝试分配 XX+n 字节)。

我发现 PHP 以未压缩的格式处理图像:我的输入图像为 8768x4282@32 位 => 每个内存副本约 150 MB。

作为解决方案,你可以检查尺寸并拒绝任何过大的尺寸,或者像我一样,在页面开始时使用 ini_set('memory_limit','1024M');(如果你的服务器有足够的内存)。
0
codam
13 年前
创建一个用透明色填充的透明图像

我很难做到这一点

<?php
// 设置图像
$img = imagecreatetruecolor(100,100);
imagesavealpha($img, true);

// 用透明色填充图像
$color = imagecolorallocatealpha($img,0x00,0x00,0x00,127);
imagefill($img, 0, 0, $color);

// 将图像保存到 file.png
imagepng($img, "file.png");

// 销毁图像
imagedestroy($img);
?>
0
thalis kalfigopoulos
15 年前
我遇到了以下关于会话和图像创建的 WRT。

在 main.php 中
<?php
(...会话正在进行中...)
$_SESSION['text']='some text...';
$imgSrc='http://foo.com/createImage.php?sid='.session_id();
echo(
'<img src="'.$imgSrc.'"/>');
unset(
$_SESSION['text']);
...
?>

在 createImage.php 中
<?php
header
('image/png');
session_id($_REQUEST['sid']);
session_start();
$img=imagecreatetruecolor(200, 30);
$text_color=imagecolorallocate($img, 200, 200, 200);
imagestring($img, 5, 5, 5, $_SESSION['text'], $text_color);
imagepng($img);
imagedestroy($img);
?>

问题:main.php 执行在 createImage.php 将文本写入图像之前结束,因此 unset($_SESSION['text']) 销毁了文本,最终导致图像为空。
解决方案:将对 unset() 的调用作为 createImage.php 的最后一个语句移动
0
eetu11 at suomi24 dot fi
15 年前
<?php

// 高亮联盟的 ID
$marked_aid = 2403;

// 数据库配置
$mysqlhost = 'localhost';
$mysqluser = 'user';
$mysqlpass = 'password';
$mysqldb = 'database';

// 建立数据库连接并选择数据库
$db = @mysql_connect($mysqlhost, $mysqluser, $mysqlpass) OR die('无法连接到数据库服务器!');
$db_select = @mysql_select_db($mysqldb) OR die('无法选择数据库!');

// 创建图像: 地图从 -400 到 400
// -> 总共 2*400+1 (+1 因为中心点为 0)
$image = imagecreate(801, 801);

// 选择背景色、普通村庄颜色和高亮联盟颜色
$color_background = imagecolorallocate($image, 255, 255, 255);
$color_normal = imagecolorallocate($image, 200, 200, 200);
$color_marked = imagecolorallocate($image, 255, 0, 0);

// 用选择的颜色填充图像背景
imagefill($image, 0, 0, $color_background);

// 从数据库中选择所有村庄,并按 ID 升序排序
// (字段从左上角到右下角编号)
$query = 'SELECT x, y, aid FROM x_world ORDER BY id ASC';
$result = @mysql_query($query) OR die('无法从 x_world 表中选择村庄!');

// 检查是否有村庄
if (mysql_num_rows($result)) {

// 选择第一个村庄
$row = @mysql_fetch_assoc($result);

// 这些变量保存当前绘制的位置
$x_pointer = 0;
$y_pointer = 0;

// Y 坐标的外层循环
for($y=400; $y >= -400; $y--) {

// X 坐标的内层循环
for ($x=-400; $x <= 400; $x++) {

// 当我们到达与当前从数据库中选择的记录匹配的坐标时:
if ($row['x'] == $x AND $row['y'] == $y) {

// 根据 AID 选择村庄颜色
if ($row['aid'] == $marked_aid) {
$color = $color_marked;
} else {
$color = $color_normal;
}

// 用选定的颜色绘制村庄
imagefilledrectangle($image, $x_pointer, $y_pointer, ($x_pointer + 1), ($y_pointer + 1), $color);

// 选择下一条记录
$row = @mysql_fetch_assoc($result);
}

// 增加 X 坐标指针
$x_pointer++;
}

// 增加 Y 坐标指针
$y_pointer++;

// 我们到达了一行的末尾,必须将 X 指针重新设置为 0
$x_pointer = 0;
}
}

// 选择所选文件类型的 HTTP 标头
header("Content-Type: image/png");

// 生成图像并打印
imagepng($image);

?>
0
Jeff Sauro
16 年前
我的 web 服务器运行的是 5.14,它不喜欢使用 imagepng() 生成的标头。它在我的本地测试服务器和另一个主机的 4.x 上运行良好。

生成的图像在浏览器(IE、Firefox)中显示,但保存到文件或插入 RTF 文件时,图像损坏。作为测试,当尝试右键单击以另存为时,图像格式无法识别。

唯一的解决方法似乎是添加额外的参数。

所以不是只有
imagepng($image); // 没用 -- 图像损坏

这个起作用了
imagepng($image,NULL,0,NULL);

并保存到磁盘,这个也起作用了
imagepng($image,$file_location,0,NULL);

Jeff
0
pm at dontspamme dot pietmarcus dot com
19 年前
回复: cbrasho at yahoo dot com

如果你使用 Apache 作为 web 服务器,你可以执行以下操作

你可以在你的网站空间中创建一个名为 'img' 的目录。
在该目录中,将有两个文件:一个 .htaccess 文件和一个 img.php 文件
.htaccess 文件包含以下代码
ErrorDocument 404 /img/img.php

img.php 文件看起来像这样

<?php
$file
= $_SERVER['REDIRECT_URL'];

$result = mysql_query('select img_blob from images where filename=\\'' . $file . '\\');
list($blob) = mysql_fetch_row($result);

header('
HTTP/1.0 200 Ok');
header("Content-type: image/jpeg");

print $blob; # 或任何可行的代码,我不使用这个
?>

如果你使用像 http://test.com/img/image1.jpeg, 这样的 URL 来访问你的图像,而该图像并不存在,通常你会得到一个 404 页面。在这种情况下,404 由 img.php 处理,它会显示所需的图像...
0
ruelle at xtof dot com
22 年前
比对任何 '/dir/pic.png' 使用 chmod 777 更好,你应该
- 测试目录是否可写 (is_writable 函数)
- 使用 chmod 700 (更安全,因为只允许 web 服务器 ID 访问)

在任何情况下,你都应该编写一个 (crontab) 脚本来更改任何创建的图像的所有者 ID。
-1
boukeversteegh at gmail dot com
13 年前
如果你关心速度,你可能已经将生成的图像缓存到文件中。在这种情况下,不要使用 "createimagefrompng" 和 "imagepng" 来输出图像。使用 fpassthru 代替。它实际上快数百倍。

<?php
header
("Content-Type: image/png");

# 生成图像的缓存文件,如果它不存在
if( !file_exists($cachefile) ) {
$im = generateimage(); # 一些代码生成一个图像资源
imagepng($im, $cachefile); # 将图像存储到缓存文件

# 不要像这样输出它:
/* imagepng($im);*/

imagedestroy($im);
}

$fp = fopen($cachefile, 'rb'); # 从缓存文件直接流式传输图像
fpassthru($fp);
exit;
?>

我已经用一个 5120x5120 (1.2Mb) 的图像进行了测试,该图像被缓存到硬盘上。使用 imagepng,传输需要 12 秒。使用 fpassthru,只需要 32ms!
-1
vicrry at yahoo dot com
16 年前
@ phpman at texmedia dot de

PNG 中的压缩范围在 0-9 之间,我认为如果你指定的压缩级别高于 9,它将被完全 "压缩",或者换句话说被抑制。

压缩级别最初是针对 JPEG 的,它在 0 - 100 之间,我认为如果你在传递给 imagepng() 之前将其除以十,它将运行良好。;)
-1
anonymous
13 年前
如果你需要多次调用 imagepng()(例如,当你想要将它发送到浏览器,但也发送到磁盘缓存时),先将你的图像写入文件,然后调用 readfile()。

PHP 在将图像发送到浏览器时会在内部使用一个临时文件,所以你不会通过两次调用 imagepng() 获得任何好处。
-2
vladson at pc-labs dot info
19 年前
为了发送 'Content-Length' 标头(就像静态图片情况下的那样),我使用 "输出处理程序",如下所示...
<?php
// 输出处理程序
function output_handler($img) {
header('Content-type: image/png');
header('Content-Length: ' . strlen($img));
return
$img;
}

// 图片输出
ob_start("output_handler");
imagepng($im);
ob_end_flush();
?>
-2
php at no dot spam dot prosa dot net
19 年前
您可以使用 `imagecreatefrompng` 函数。

(我假设您已经知道如何从 URL 获取文本。)

剩下的唯一事情就是使用正确的颜色将文本放到图像上。

<?php

$im
= @imagecreatefrompng($imgname);

$text_color = imagecolorallocate ($im, $Red,$Green,$Blue);

imagestring ($im, 3, 5, 15, $SomeTextFromURL, $text_color);

?>

此致,
Peter Berkhout。
-2
matt at mattbostock dot com
15 年前
要更改 24 位 PNG 的背景以实现 IE6 中的优雅降级,PNG 文件需要一个 bKGD 块。

<?php
// 在 PNG 文件中插入一个 BKGD 块以实现 IE6 中的优雅图像降级
$bgColor = array(250, 250, 250);
$pngData = bin2hex(file_get_contents($filename));

$idatMarker = '200049444154';
$bkgdMarker = '624b4744';

$bkgdChunk = '0006' . $bkgdMarker;
foreach (
$bgColor as $bit)
{
$bkgdChunkData .= '00' . dechex($bit);
}
$bkgdChunk .= $bkgdChunkData;
$bkgdChunk .= dechex(crc32(pack('H*', $bkgdMarker . $bkgdChunkData))) . '0000';

$parsed = explode($idatMarker, $pngData, 2); // 通过第一个“IDAT”块拆分文件
$pngData = pack('H*', $parsed[0] . $bkgdChunk . $idatMarker . $parsed[1]);
file_put_contents($cachedFilename, $pngData);
?>
-2
cbrasho at yahoo dot com
19 年前
将您的图片存储在数据库中听起来很棒,但会给您带来很多麻烦。
在数据库中存储图像,您将有一个脚本 show.php 会出现在 <img> 标签中:<img src='show.php?img_id=$some_id'>
但是,如果您想让 REGISTER GLOBALS = OFF,您就遇到了麻烦,而且没有办法(至少就我所知)解决这个问题,只能将图像从数据库中放到一个文件中,并将相应的文件名放到 <img> 标签中。但这又带来另一个问题:对页面的同时访问。因此,您必须找到一种方法为每个同时访问页面的人提供唯一的图片文件名。解决方案可能是使用会话。最终,您将为一个非常简单的问题编写一个非常复杂的 PHP 脚本。因此,基本思想是“除非您确切知道自己在做什么,否则不要将图片存储在 blob 中”。
-5
phpman at texmedia dot de
16 年前
当我将 PHP 版本从 4 更改为 5 时,我发现 PHP5 对 imagepng() 的处理比 PHP4 更严格。我曾经使用过

imagepng($image,'',90);

来降低图像质量,而不将其另存为文件。质量参数完全不受支持,我之前使用过 imagejpg,并简单地将函数更改为 imagepng,而不考虑现有的参数。它没有影响,并且在 PHP4 中没有错误。但是在 PHP5 中,图像将不再显示。因此,您必须将其删除以获得标准

imagepng($image);
-8
bart at resolume dot com
18 年前
如果您想调整 PNG-24 图像的大小并保留 alpha 通道,您需要在使用 imagecreatetruecolor() 创建目标图像后立即在目标图像上设置 imagealphablending($im_dest, false),并在保存图像之前在上面执行 imagesavealpha($im_dest, true)。

<?php

$im
= ImageCreateFromPNG('redfade.png');

$im_dest = imagecreatetruecolor (500, 300);
imagealphablending($im_dest, false);

imagecopyresampled($im_dest, $im, 0, 0, 0, 0, 300, 300, 500, 300);

imagesavealpha($im_dest, true);
imagepng($im_re, 'small_redfade.png');

?>
-5
dws at mrao dot cam dot ac dot uk
19 年前
大概它在成功时返回 true,在失败时返回 false,尽管文档中没有明确说明。
-10
awalton at gmail dot com
18 年前
PNG 图像(以及任何图像)都可以存储在 MySQL blob 字段中,但是如果您想这样做,您需要将图像流序列化成更合适的格式。我建议使用 base64_encode() 和 base64_decode()。(只需 fopen() 文件,fread() 内容,base64_encode() 字符串,然后发送您的 SQL 查询(使用 addslashes()/stripslashes() 提高安全性)。)

这在整个站点中已经发布了无数次,但仍然很糟糕,很多用户根本不理解这一点,而没有充分利用它的潜力。

我还建议,如果您以这种方式处理图像,请在 PHP 可以访问的某个位置保留一个图像缓存文件夹(可能甚至在您的 webroot 之外的某个位置?)。这样,如果您的网站被大量流量淹没,它就不会拖垮 SQL 服务器。
To Top