Apache httpd + php實現圖片縮圖訪問
Apache httpd + php + imagic 實現圖片縮圖訪問
環境:CentOS7, Apache httpd 2.4, php 5.4.16
實現思路
利用httpd的重寫規則把特殊的URL訪問對映到PHP指令碼,實現縮圖的返回。PHP利用ImageMagic元件實現縮圖檔案生成。
需要用到的東西較多,而且需要安裝不少東西。下文將詳細介紹具體操作,以節省您的時間,告訴請出門左拐。
實現需要的元件安裝
yum install -y httpd
yum install -y httpd-devel apr apr-devel libtool
yum install php
yum install -y php-devel
yum install -y php-pear
yum install -y ImageMagick
yum install -y ImageMagick-devel
pecl install imagick
新增extension=imagick.so到/etc/php.d/imagemgick.ini(需要新建)
由於pecl實際需要編譯原始碼,所以需要安裝開發包,如果沒有gcc,需要用yum install -y gcc 安裝。
縮放實現
通過Apache httpd的Rewrite重寫規則實現URL重定向。
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^/(.+\.(jpg|jpeg|png|bmp)@[-|\d]+x[-|\d]+).*$ /resize.php?file=$1 [L]
上面配置需要加入httpd的配置檔案中,我加到了自己位於/etc/httpd/conf.d/xxx.conf檔案中。
上面的正則表示式可以依據不同的URL進行修改,含義是:
把以/開始,任意1一個或多個字元開頭後跟隨”.jpg”, “.jpeg”…並用“@”連線的引數,引數採用“-”或者數字作為寬度,x字元表示乘號(實際為字元x),後面跟隨高度。
如果希望得到寬度200畫素的圖片,可以用”200x-“,如果希望得到200x200的圖片(建議不要,以免縱橫比失真), 可以用“200x200”,如果希望得到高度限定為200,可以採用”-x200”的方式。
如下:
-
- http://localhost/[email protected]
- http://localhost/[email protected]
注意:後面參考文章用的“!”符號作為分隔符在Linux系統中就變成了執行指令了(很危險)
resize.php指令碼的實現,可以直接用。
<?php
$ROOT_PATH = "/var/www/html/";
$fileParam = $_REQUEST['file'];
preg_match('/^(.+\.(jpg|jpeg|png|bmp))@([-|\d]+)x([-|\d]+).*$/', $fileParam, $matches);
if ($matches){
$path = $ROOT_PATH.$matches[0];
$srcPath = $ROOT_PATH.$matches[1];
$w = $matches[3];
$h = $matches[4];
$w = preg_match('/^\d+$/i', $w) ? intval($w) : 0;
$h = preg_match('/^\d+$/i', $h) ? intval($h) : 0;
if (file_exists($path) == false){ // 如果縮圖不存在,則建立它
$image = new Imagick($srcPath);
$len = $image->getImageSize();
if($len < 1024 * 50){ // 如果原圖小於50k,則不縮放
$path = $srcPath;
}else{
$real_w = $image->getImageWidth();
$real_h = $image->getImageHeight();
// 以下4行程式碼可以提升效能
$image->setImageCompression(Imagick::COMPRESSION_JPEG);
$image->setImageCompressionQuality(75); // 設定圖片質量
$image->stripImage();
$image->setImageFormat('JPEG');
$image->thumbnailImage($w, $h);
$image->writeImages($path, true);
}
$image->clear();
$image->destroy();
}
@header("Content-Type:image/png");
echo file_get_contents($path);
}else{
echo "Error file parameter.";
}
?>
由於/var/www/html目錄是root使用者的,所以為了實現縮圖生成,需要該目錄可以寫入,需要設定如下:
- 修改該目錄為其他使用者可寫
chmod -R o+w /var/www/html
- 修改該目錄的SELinux角色為httpd_sys_rw_content_t
chcon -R -t httpd_sys_rw_content_t /var/www/html
httpd_sys_rw_content_t httpd_sys_content_t public_content_rw_t 這三個的區別在哪兒呢?
httpd_sys_content_t Read-only directories and files used by Apache
httpd_sys_rw_content_t Readable and writable directories and files used by Apache. Assign this to directories where files can be created or modified by your application, or assign it to files directory to allow your application to modify them.
按我的理解,如果httpd是訪問系統目錄,那麼需要httpd_sys_*_t的策略,如果是普通目錄,可以採用public_content_*_t, 讀寫需要rw.