fre*_*ed2 6 php apache2 imagemagick imagick
在将现有的,稳定的网站转移到新服务器的过程中,我遇到了一些间歇性问题,其中包含一些使用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.
Run Code Online (Sandbox Code Playgroud)
代码可能已经使用了至少5年没有问题.
在转移到一个新的,更快的服务器(从Debian Squeeze到Ubuntu 12.04)时,我遇到了一个问题,即大约50%的时间没有显示图像,而是服务器发送一个0字节的"png文件".没有PHP错误或服务器错误.
根据图像是否成功发送,将发送不同的标头:
成功的图片标题:
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
Run Code Online (Sandbox Code Playgroud)
图像标题失败:
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
Run Code Online (Sandbox Code Playgroud)
有没有人有任何想法为什么会这样?
有没有办法'强制'png图像被发送分块,因为我想知道这是否是问题的根源.我已经尝试了各种变通方法,我通过PHP的header()函数发送图像大小或"Transfer-Encoding:chunked"作为标题,但是没有用,并且在这些情况下浏览器声明图像已损坏.
<?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);
?>
Run Code Online (Sandbox Code Playgroud)
更新:如果它有助于确定问题的位置:
我已经创建了一个适用于所有情况的狡猾解决方案,作为权宜之计.我所做的是创建图像,将其作为临时文件保存到磁盘.打开文件并使用passthru()将其发送到客户端,然后从磁盘中删除该文件.很麻烦,我宁愿做'整洁'的方式,但它告诉我问题是以某种方式与这两行相关联:header('Content-type:image/png'); echo $img->getImage();Apache,PHP或Imagick未能处理资源.
| 归档时间: |
|
| 查看次数: |
1065 次 |
| 最近记录: |