使用Imagick动态影像创作/ Apache的头 [英] Dynamic image creation/Apache headers using Imagick

查看:202
本文介绍了使用Imagick动态影像创作/ Apache的头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在传输现有的,稳定的,网站,我已经有点code的创建使用动态图像Imagick遇到的间歇性问题的新服务器。

While transferring an existing, stable, website to a new server I've run into an intermittent problem with a bit of code that creates images dynamically using Imagick.

在code解析一个GET查询(如example.com/image.php?ipid=750123&r=0&w=750&h=1000),然后规模和旋转存储在服务器上的图像和它提供给客户端。

The code parses a GET query (eg example.com/image.php?ipid=750123&r=0&w=750&h=1000) and then scales and rotates an image stored on the server and serves it to the client.

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

在code可能已经使用了至少5年没有问题。

The code has probably been used for at least 5 years with no problems.

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

On transferring to a new, much faster, server (from Debian Squeeze to Ubuntu 12.04), I encounter a problem where about 50% of the time the image does not display, and instead the server sends a 'png file' of 0 bytes. There are no PHP errors or server errors.

根据图像是否被成功发送,不同的页眉发送:

Depending on whether the images is sent successfully or not, different headers are sent:

成功映像头:

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

没有人有任何想法,为什么发生这种情况?

Does anyone have any ideas why this is happening?

有没有一种方法,以力发送分块,因为我不知道这是否是问题的根源的PNG图像。我试过,我发送图像的大小,或者各种变通办法传输编码:分块作为通过PHP的标题中的header()函数,但没有工作,在这种情况下,浏览器的状态已损坏的图片

Is there a way to 'force' the png images to be sent chunked, as I wonder if that is at the root of the problem. I've tried various workarounds where I send the image size, or 'Transfer-Encoding: chunked' as a header via PHP's header() function, but did not work, and in these cases the browser states the image is corrupted.

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

更新:万一它有助于确定故障的位置:

我已经创建了一个解决办法cludgy这在所有的情况下,可以作为一个权宜之计。我要做的就是创建图像,将其保存到磁盘的临时文件。打开文件,并使用中继()将其发送到客户端,然后删除磁盘上的文件。烦琐,我宁愿做的整洁的方式,但它表明我的问题在某种程度上与这两个线相关:标题(内容类型:image / PNG');回声img- $&GT;的getImage(); 并通过了Apache,PHP或Imagick未能处理资源

I've created a cludgy workaround which works in all cases, as a stopgap measure. What I do is create the image, save it to disk as a temporary file. Open the file and send it to the client using passthru() and then delete the file from disk. Cumbersome, and I'd rather do it the 'tidy' way, but it suggests to me the problem is somehow associated with these two lines: header('Content-type:image/png'); echo $img->getImage(); and a failure by Apache, PHP or Imagick to handle the resource.

推荐答案

我以前也有非常类似这样的一个问题,而且还涉及到有一个头与一个301或302状态code正向第二个请求。有些浏览器不遵守

I've had an issue very similar to this before and it was related to the second request having a header forward with a 301 or 302 status code. Some browsers don't follow

都返回的图像200或者失败中返回一个重定向?

Are both images returning 200 or is the failed one returning a redirect ?

这篇关于使用Imagick动态影像创作/ Apache的头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆