gpt4 book ai didi

php - 使用 Imagick 的动态图像创建/Apache header

转载 作者:可可西里 更新时间:2023-11-01 13:22:55 24 4
gpt4 key购买 nike

在将现有的稳定网站转移到新服务器时,我遇到了一些使用 Imagick 动态创建图像的代码的间歇性问题。

代码解析 GET 查询(例如 example.com/image.php?ipid=750123&r=0&w=750&h=1000),然后缩放和旋转存储在服务器上的图像并将其提供给客户端。

ipid = id for an image stored on server
r = degrees of rotation
w = width to display
h = height to display.

该代码可能已经使用了至少 5 年没有出现问题。

在转移到一个新的、更快的服务器(从 Debian Squeeze 到 Ubuntu 12.04)时,我遇到了一个问题,大约 50% 的时间图像不显示,而是服务器发送一个“png 文件” 0 字节。没有 PHP 错误或服务器错误。

根据图片发送成功与否,发送不同的headers:

成功的图片标题:

Connection: Keep-Alive
Content-Type: image/png
Date: Tue, 23 Jul 2013 17:03:32 GMT
Keep-Alive: timeout=5, max=76
Server: Apache/2.2.22 (Ubuntu)
Transfer-Encoding: chunked
X-Powered-By: PHP/5.3.10-1ubuntu3.7

失败的图片标题:

Connection  Keep-Alive
Content-Length 0
Content-Type image/png
Date Tue, 23 Jul 2013 17:03:31 GMT
Keep-Alive timeout=5, max=78
Server Apache/2.2.22 (Ubuntu)
X-Powered-By PHP/5.3.10-1ubuntu3.7

有人知道为什么会这样吗?

有没有办法“强制”将 png 图像分块发送,因为我想知道这是否是问题的根源。我尝试了各种解决方法,通过 PHP 的 header() 函数发送图像大小或“Transfer-Encoding: chunked”作为 header ,但没有用,在这些情况下,浏览器指出图像已损坏。

<?php

//Class used to connect to Imagick and do image manipulation:
class Images
{
public $image = null;

public function loadImage($imagePath){

$this->image = new Imagick();
return $this->image->readImage($imagePath);
}

public function getImage(){

$this->image->setImageFormat("png8");
$this->image->setImageDepth(5);
$this->image->setCompressionQuality(90);
return $this->image;
}

// Resize an image by given percentage.
// percentage must be set as float between 0.01 and 1
public function resizeImage ($percentage = 1, $maxWidth = false, $maxHeight = false)
{
if(!$this->image){return false;}
if($percentage==1 && $maxWidth==false && $maxHeight == false){return true;}

$width = $this->image->getImageWidth();
$height = $this->image->getImageHeight();

$newWidth = $width;
$newHeight = $height;

if($maxHeight && $maxWidth){
if($height > $maxHeight || $width > $maxWidth){

$scale = ($height/$maxHeight > $width/$maxWidth) ? ($height/$maxHeight) : ($width/$maxWidth) ;
$newWidth = (int) ($width / $scale);
$newHeight = (int) ($height / $scale);
}
}else{

$newWidth = $width * $percentage;
$newHeight = $height * $percentage;
}
return $this->image->resizeImage($newWidth,$newHeight,Imagick::FILTER_LANCZOS,1);

}

public function resizeImageByWidth ($newWidth)
{
if ($newWidth > 3000){
$newWidth = 3000; //Safety measure - don't allow crazy sizes to break server.
}

if(!$this->image){return false;}

return $this->image->resizeImage($newWidth,0,Imagick::FILTER_LANCZOS,1);

}

public function rotateImage($degrees=0)
{
if(!$this->image){return false;}
return $this->image->rotateImage(new ImagickPixel(), $degrees);
}

}


//(simplified version of) procedural code that outputs the image to browser:

$img = new Images();

$imagePath = '/some/path/returned/by/DB/image.png';

if($imagePath){
$img->loadImage($imagePath);

$width = $img->image->getImageWidth();
$height = $img->image->getImageHeight();

if (!$img->resizeImageByWidth($newWidth))
{
die ("image_error: resizeImage() could not create image.");
}

if($rotation > 0){
if (!$img->rotateImage($rotation))
{
die ("image_error: rotateImage() could not create image.");
}
}

}else{

die("image_error: no image path specified");
}

header('Content-type:image/png');
echo $img->getImage();

exit(0);
?>

更新:如果它有助于确定问题的位置:

作为权宜之计,我创建了一个适用于所有情况的笨拙的解决方法。我所做的是创建图像,将其作为临时文件保存到磁盘。打开文件并使用 passthru() 将其发送到客户端,然后从磁盘中删除该文件。很麻烦,我宁愿用“整洁”的方式来做,但它向我暗示问题与这两行有某种关联: header('Content-type:image/png'); echo $img->getImage(); 以及 Apache、PHP 或 Imagick 处理资源失败。

最佳答案

我之前遇到过一个与此非常相似的问题,它与第二个请求有关,该请求的 header 转发带有 301 或 302 状态代码。一些浏览器不遵循

两个图像都返回 200 还是失败的图像返回重定向?

关于php - 使用 Imagick 的动态图像创建/Apache header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17816837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com