首頁 >後端開發 >php教程 >Nginx下php如何動態裁切圖片

Nginx下php如何動態裁切圖片

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2016-07-25 09:13:041088瀏覽

以前寫過一篇也是關於高性能PHP圖片動態裁剪方案的文章,那文章使用的是nginx Cache和rewrite實現的,當然再加上CDN,那個方案存在一個問題就是圖片並沒有實際生成,而是以二進制的形式存在緩存中。如果快取失效了那麼還需要請求php再次產生。如果說到差異這是我暫且認為的。

利用空餘時間,新增了靜態生成圖片支持,支持對圖片3種模式切換,在門戶網站自動對圖片尺寸進行裁剪,減少伺服器頻寬,圖片裁剪使用了Imagick組件。

一、思路再現: 1.先寫好請求伺服器產生圖片動態腳本,主要就是對圖片進行等比縮放計算+裁切。 2.確定想要產生的url規則,例如http://www.domain.com/www/300×200-1/test.jpg。 3.對瀏覽器做快取處理。 4、結束。

二、動態裁切圖片的PHP腳本

  1. /**

  2. * Author pony_chiang
  3. * 高效能影像裁切方案
  4. * 需要php-imagick擴充
  5. */
  6. ini_set ( "memory_limit", "80M" );
  7. // 請求位址例如http://yourdomain.com/resize.php?site=www&width=300&height=200&mode=2&path=uploadfile/helloworld.png

  8. // nginx重寫規則rewrite=uploadfile/helloworld.png
  9. // nginx重寫規則rewrite ^( [^.]*)/s/(.*)/(d+)x(d+)-(d)/(.*) $1/s/resize.php?site=$2&width=$3&height=$4&mode=$5 &path=$6 last;
  10. $path = trim ( $_GET ['path'] );

  11. $mode = intval ( $_GET ['mode'] );
  12. $ site = trim ( $_GET ['site'] );
  13. $width = intval ( $_GET ['width'] );
  14. $height = intval ( $_GET ['height'] );
  15. $site_list = array ('www' => '/mnt/webroot/test/' );

  16. $orig_dir = dirname ( __FILE__ );

  17. if (! array_key_exists ( $site, $site_list )) {
  18. header ( 'HTTP/1.1 400 Bad Request' );
  19. exit ();
  20. }
  21. if ( $mode > 3 || $mode header ( 'HTTP/1.1 400 Bad Request' );

  22. exit ();
  23. }
  24. $orig_file = $site_list [$site] . $path;

  25. if (! file_exists ( $orig_file )) {
  26. header ( 'HTTP/1.1 404 Not Found' );
  27. exit ();
  28. }
  29. $file_ext = '.' . pathinfo ( $path, PATHINFO_EXTENSION );

  30. $file_name = basename ( $path, $file_ext );

  31. $save_path = "{$orig_dir}/{$site}/{$width}x{$height}-{$mode}/{$path}";
  32. $save_dir = dirname ( $save_path );
  33. if (! file_exists ( $save_dir ))

  34. wpx_mkdir ( $save_dir );
  35. $target_width = $width;

  36. $target_height =$target_height = $width;
  37. $target_height = $width;
  38. $height = $height
  39. $new_width = $target_width;

  40. $new_height = $target_height;
  41. $image = new Imagick ( $orig_file );
  42. list ( $orig_width, $orig_width, $orig_height type, $attr ) = getimagesize ( $orig_file );
  43. if ($mode == "0") {

  44. //等比縮放圖片
  45. $new_height = $orig_height * $new_width / $orig_width;
  46. if ($new_height > $target_height) {
  47. $new_width = $orig_width * $target_height / $orig_height;
  48. $0 } else if ($mode == "2") {
  49. // 放大並裁切圖片
  50. $desired_aspect = $target_width / $target_height;
  51. $orig_aspect = $orig_width / $orig_height;
  52. if ($desired_aspect > $orig_aspect) {

  53. $trim = $orig_height - ($orig_width / $desired_aspect);
  54. $image->cropImage ( $orig_width - $orig, $orig, $orig, 0, $trim / 2 );
  55. error_log ( "HEIGHT TRIM $trim" );
  56. } else {
  57. $trim = $orig_width - ($orig_height * $desired_aspect);
  58. $image- >cropImage ( $orig_width - $trim, $orig_height, $trim / 2, 0 );
  59. } bbs.it-home.org
  60. }
  61. $image->resizeImage ( $new_width, $new_height, imagick::FILTER_LANCZOS, 1 );

  62. $image->writeImage ( $save_path );
  63. header ( 'Content-Type: image/jpeg' );
  64. header ( 'Content-Type: image/jpeg' );
  65. header ( 'Content-Type: image/jpeg' );
  66. er ( Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
  67. echo file_get_contents ( $save_path );
  68. return true;
  69. // 循環產生目錄

  70. function wpx_mkdir($dir, $mode = 0777) {
  71. if (is_dir ( $dir ) || @mkdir ( $dir, $mode ))
  72. return true
  73. if (! wpx_mkdir ( dirname ( $dir ), $mode ))
  74. return false;
return @mkdir ( $dir, $mode );
}
複製程式碼

三、nginx.conf配置

  1. server {

  2. listen 80;
  3. server_name test.yourdomain.com;
  4. root /mnt/web /test;
  5. index index.php;
  6. expires 30d;
  7. location /s {

  8. #只有當沒有產生這張照片時才呼叫動態裁切
  9. if (!-e $request_filename) {
  10. rewrite ^([^.]*)/s/(.*)/(d+)x(d+)-(d)/(.*) $1/s/resize .php?site=$2&width=$3&height=$4&mode=$5&path=$6 last;
  11. break;
  12. }
  13. }
  14. error_page 404 403 402 5003 504 /404.html;

  15. location = /404.html {
  16. }
  17. location ~ .php$ {

  18. fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  19. includefastcgi_params;
  20. }
  21. }

  22. 複製程式碼
說明,強調下關於瀏覽器快取的文章,不管是否是透過php產生的圖片也好,還是使用nginx快取產生的圖片也罷,在php程式碼中加入一行

header('Last-Modified: ' .gmdate('D, d M Y H:i:s') . ' GMT' );
  1. 複製程式碼
對使用CDN有莫大的幫助。 客戶端第一次存取此文件的http狀態碼是200,刷新後狀態碼一直都是304了,明白其中的好處了,本地客戶端快取了,節省頻寬哦。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn