PHP Conference Japan 2024

imagepng

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

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

描述

imagepng(
    GdImage $image,
    资源|字符串| $file = null,
    整数 $quality = -1,
    整数 $filters = -1
): 布尔值

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

参数

image

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

file

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

注意:

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

quality

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

filters

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

警告

filters 参数会被系统 libgd 忽略。

返回值

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

警告

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

错误/异常

如果 quality 无效,则抛出 ValueError

变更日志

版本 描述
8.4.0 现在如果 quality 无效,则抛出 ValueError
8.0.0 image 现在期望一个 GdImage 实例;以前,期望一个有效的 gd 资源

示例

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

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

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

参见

添加注释

用户贡献的注释 33 条注释

matteosistisette at gmail dot com
13 年前
压缩参数的名称“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 是最大压缩(质量不会改变)。
匿名
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...
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);

?>
luxian.m [at] gmail [dot] com
16 年前
如果你想打开一个带有 Alpha 通道的 PNG 图片,你需要做一些类似下面的操作

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


我花了将近一天的时间才找出为什么 Alpha 混合不起作用。我希望这对其他人也有用 :)
r.lomas at infonie.fr
14 年前
我刚刚在一个非常愚蠢的问题上浪费了大约 4 个小时。我本地服务器上的图像不知何故损坏了,因此无法在浏览器中显示。经过大量的查找和测试,包括在我的电脑上重新安装了几次 Apache,我最终将问题追溯到一个包含的文件。
问题不在于空格,而是在我其中一个包含文件开头处的 UTF BOM 编码字符……
所以要注意你的包含文件!
确保它们没有使用 UTF 编码,或者以不带 BOM 的 UTF 编码。
希望它能节省一些人的时间。
geompse at gmail dot com
12 年前
使用变量作为文件名时要小心。
PHP 在切换到 PHP5.4 后,使用 $filename 的行为有所不同:PHP5.3 将 $filename='' 和 $filename=NULL 视为相同的方式(例如,没有警告)
<?php
$im
= imagecreatetruecolor(10,10);
imagepng($im,'',9); # Warning: imagepng(): Filename cannot be empty
imagepng($im,NULL,9); # 预期效果
imagedestroy($im);
?>
johnbeech at mkv25.net
21 年前
PNG 文件已经是压缩的。它们使用无损压缩算法。如果您使用的是高色彩图像,则压缩效果有限。对于低色彩图像(16 或 256 色),压缩效果要好得多。

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

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

<?php
header
('Content-Disposition: Attachment;filename=image.png');
header('Content-type: image/png');
?>
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
?>
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
php dot net at phor dot net
11 年前
如果您直接在响应客户端请求时输出 PNG,则必须检查 Web 服务器配置。

某些客户端可能会使用 <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">Accept 标头</a> 请求您的图像,其值为 image/*。Apache 和可能其他服务器的默认配置默认情况下不允许您的脚本对此请求做出响应。

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

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



<?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 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;
}
?>

祝你好运,
尼古拉·纳莫洛凡,摩尔多瓦
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);

另外,你忘记了 imagedestroy,并且你在 imagepng 中使用了在你帖子中未定义的随机变量
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);
?>
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();

/*
在这里,你可以根据需要修改 $imagevariable
*/
?>
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).'">';
klaus at hax dot at
7 年前
显然,从 PHP 5.5 到 5.6 有了一些变化。

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

ImagePng($image, NULL);

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

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

作为解决方案,你可以检查尺寸并拒绝任何过大的图像,或者像我一样,在页面开始时使用 ini_set('memory_limit','1024M');(如果你的服务器有足够的内存)。
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);
?>
thalis kalfigopoulos
15 年前
我在会话和图像创建方面遇到了以下问题。

在 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 的最后一行。
[email protected]
16 年前
<?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);

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

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

唯一解决方法似乎是添加其他参数。

因此,不仅仅是
imagepng($image); // 不起作用 - 图像损坏

这有效
imagepng($image,NULL,0,NULL);

以及保存到磁盘,这也有效
imagepng($image,$file_location,0,NULL);

Jeff
[email protected]
20 年前
回复:[email protected]

如果您使用 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,而该 URL 不存在,通常您会收到 404 页面。在这种情况下,404 由 img.php 处理,它会调出所需的图像……
[email protected]
22 年前
比对任何“/dir/pic.png”使用 chmod 777 更好的是
- 测试目录是否可写(is_writable 函数)。
- 使用 chmod 700(更安全,因为只允许 Web 服务器 ID 访问)。

无论如何,您应该编写一个(crontab)脚本以更改创建的所有图像的所有者 ID。
[email protected]
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,只花了 32 毫秒!
[email protected]
16 年前
@ [email protected]

PNG 的压缩范围是 0-9,我认为如果指定大于 9 的压缩级别,它将被完全“压缩”,或者换句话说,会被抑制。

压缩级别最初是针对 JPEG 的,范围是 0-100,我认为如果你在传递给 imagepng() 之前将其除以十,它将可以正常工作。;)
匿名用户
14 年前
如果您需要多次调用 imagepng()(例如,当您想将其发送到浏览器,但也发送到磁盘缓存时),请先将您的图像写入文件,然后对其调用 readfile()。

PHP 在将图像发送到浏览器时内部使用临时文件,因此通过两次调用 imagepng() 您将一无所获。
[email protected]
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();
?>
[email protected]
19 年前
您可以使用 imagecreatefrompng 函数

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

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

<?php

$im
= @imagecreatefrompng($imgname);

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

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

?>

此致,
Peter Berkhout。
[email protected]
15 年前
要更改 24 位 PNG 的背景以在 IE6 中实现优雅降级,PNG 文件需要一个 bKGD 块

<?php
// 将 BKGD 块插入 PNG 文件以在 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);
?>
[email protected]
20 年前
将您的图片存储在数据库中听起来很棒,但会给您带来很多麻烦。
将图像存储在数据库中,您将有一个 show.php 脚本,它将出现在 <img> 标签中:<img src='show.php?img_id=$some_id'>
但是,如果您希望 REGISTER_GLOBALS = OFF,那么您就遇到了麻烦,并且没有办法(至少据我所知)解决这个问题,除非将图像从数据库放入文件中,并将相应的文件名放入 <img> 标签中。但这带来了另一个问题:对页面的同时访问。因此,您必须找到一种方法为每个对页面的同时访问提供唯一的图片文件名。解决方案可能是使用会话。这就是您最终为一个非常简单的问题创建了一个非常复杂的 PHP 脚本的方式。因此,基本思想是“除非您确切地知道自己在做什么,否则不要将图片存储在 blob 中”。
[email protected]
17 年前
当将 PHP 版本从 4 更改为 5 时,我发现 PHP5 处理 imagepng() 比 PHP4 更严格。我曾使用

imagepng($image,'',90);

来降低图像质量,而无需将图像保存为文件。质量参数根本不受支持,我之前使用过 imagejpg,并且只是简单地将函数更改为 imagepng,而没有注意现有参数。它没有问题,并且在 PHP4 中没有错误。但在 PHP5 中,图像将不再显示。因此,您必须将其删除以获得标准

imagepng($image);
[email protected]
19 年前
据推测,它在成功时返回 true,在失败时返回 false,尽管文档实际上没有这样说。
To Top