使用 GD 的代码以 "image cannot be displayed" 的错误结束

Code utilizing GD ending up in an error that "image cannot be displayed"

我的代码如下:

<?php
session_start();
$img=imagecreatetruecolor(150,50);

$white=imagecolorallocate($img,255,255,255);
$black=imagecolorallocate($img,0,0,0);
$red=imagecolorallocate($img,255,0,0);
$pink=imagecolorallocate($img,200,0,150);
$grey=imagecolorallocate($img,150,150,150);
$blue=imagecolorallocate($img,0,204,255);
$redd=imagecolorallocate($img, 153, 0,0);
function randomString($length){
    $chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ023456789";
    srand((double)microtime()*1000000);
    $str="";
    while($i<=$length){
        $num=rand() % 33;
        $tmp=substr($chars,$num,1);
        $str.=$tmp;
        $i++;
    }
    return $str;
}
for($i=0;$i<=rand(1,5);$i++)
{
    $color=(rand(1,2)==1)? $grey:$white;
    imageline($img, rand(5,50),rand(5,50),rand(50,150) , rand(5,50), $color);
}
$ran=randomString(rand(3,6));
$_SESSION['captcha']=$ran;
imagefill($img,0,0,$redd);
imagettftext($img,14,7,23,27,$black,"fonts/times_new_yorker.ttf",$ran);
imagettftext($img,16,10,18,30,$white,"fonts/times_new_yorker.ttf",$ran);
header("Content-type:image/png");
imagepng($img);
imagedestroy($img);

?>

昨天这按预期工作。但是现在 Firefox 显示一条消息:

This image cannot be displayed, because this contains error.

当我搜索任何解决方案时,似乎每个人都在谈论启用 GD。但是在我的代码中 GD 启用的,这个代码直到今天早上都运行良好。

谁能帮我解决这个问题?

图片无法显示,因为PHP报错,header('Content-Type: image/png')告诉它把页面显示为图片。

要查看错误,您应该删除以下部分:

header("Content-type:image/png");
imagepng($img);
imagedestroy($img);

或者更好的是,用 if (!isset($_GET['debug'])) 语句包围它。这样您就可以将 ?debug=1 附加到 URL 并查看所有可能的 PHP 错误,而图像仍然正常显示。

有几种可能的解决方案可以解释为什么您的代码可能会在不更改代码的情况下停止工作。我的猜测是你以某种方式篡改了环境。

  • session_start() 需要将会话数据存储在本地驱动器的目录中。您的 PHP 可以访问该目录吗?
  • 字体 fonts/times_new_yorker.ttf 可能会消失。
  • 您可以将脚本移动到 Linux 机器,其中字母大小写很重要。您确定字体路径中的任何地方都不应包含大写字符吗?

此外,还有一些提示:

  • 你不需要调用srand(),它会自动初始化。 (我假设你来自 C/C++ 背景)。
  • 您应该使用 mt_rand(),而不是使用 rand(),因为它更快并且提供更好的随机性。
  • 不应使用幻数,而应使用有意义的表达式(例如,将 % 33 替换为 % strlen($chars))。
  • 由于你好像显示验证码,考虑把0O1l等同于"character",这样比较合理用户错误被原谅。 (如果您已经这样做了,请原谅。)