Home >Backend Development >PHP Tutorial >How to dynamically crop images in PHP under Nginx

How to dynamically crop images in PHP under Nginx

WBOY
WBOYOriginal
2016-07-25 09:13:041047browse

I once wrote an article about a high-performance PHP image dynamic cropping solution. That article was implemented using nginx Cache and rewrite. Of course, coupled with CDN, a problem with that solution is that the image is not actually generated, but Stored in cache in binary form. If the cache fails, you need to request php to generate it again. As for the difference, this is what I think for the time being.

Use your spare time to add support for statically generated images, support switching between 3 image modes, automatically crop the image size on the portal website, reduce server bandwidth, and use the Imagick component for image cropping.

1. Reproduction of ideas: 1. First write a dynamic script that requests the server to generate a picture, which mainly performs proportional scaling calculation + cropping of the picture. 2. Determine the URL rule you want to generate, such as http://www.domain.com/www/300×200-1/test.jpg. 3. Caching the browser. 4. End.

2. PHP script for dynamically cropping images

  1. /**

  2. * Author pony_chiang
  3. * High-performance image cropping solution
  4. * Requires php-imagick extension
  5. */
  6. ini_set ( "memory_limit", "80M" );

  7. // Request address such as http:// yourdomain.com/resize.php?site=www&width=300&height=200&mode=2&path=uploadfile/helloworld.png

  8. // nginx rewrite rules rewrite ^([^.]*)/s/(.*)/(d+) x(d+)-(d)/(.*) $1/s/resize.php?site=$2&width=$3&height=$4&mode=$5&path=$6 last;

  9. $path = trim ( $_GET ['path'] );

  10. $mode = intval ( $_GET ['mode'] );
  11. $site = trim ( $_GET ['site'] );
  12. $width = intval ( $_GET ['width'] );
  13. $height = intval ( $_GET ['height'] );

  14. $site_list = array ('www' => '/mnt/webroot/test /' );

  15. $orig_dir = dirname ( __FILE__ );

  16. if (! array_key_exists ( $site, $site_list )) {
  17. header ( 'HTTP/1.1 400 Bad Request' );
  18. exit ();
  19. }

  20. if ($mode > 3 || $mode < 0) {

  21. 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 );< ;/p>
  33. if (! file_exists ( $save_dir ))

  34. wpx_mkdir ( $save_dir );

  35. $target_width = $width;

  36. $target_height = $height;< /p>
  37. $new_width = $target_width;

  38. $new_height = $target_height;
  39. $image = new Imagick ( $orig_file );
  40. list ( $orig_width, $orig_height, $type, $attr ) = getimagesize ( $orig_file );

  41. if ($mode == "0") {

  42. //Constantly scaled image
  43. $new_height = $orig_height * $new_width / $orig_width;
  44. if ($new_height > $target_height) {
  45. $new_width = $orig_width * $target_height / $orig_height;
  46. $new_height = $target_height;
  47. }
  48. } else if ($mode == "2") {
  49. // Zoom in and crop the image
  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_height - $trim, 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 ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
  65. echo file_get_contents ( $save_path );
  66. return true;

  67. < ;p>// Loop to generate directories
  68. function wpx_mkdir($dir, $mode = 0777) {
  69. if (is_dir ( $dir ) || @mkdir ( $dir, $mode ))
  70. return true;
  71. if (! wpx_mkdir ( dirname ( $dir ), $mode ))
  72. return false;
  73. return @mkdir ( $dir, $mode );
  74. }

Copy code

3. nginx.conf configuration

  1. server {

  2. listen 80;
  3. server_name test.yourdomain.com;
  4. root /mnt/webroot/test;
  5. index index.php;
  6. expires 30d;

  7. location /s {

  8. #Dynamic cropping is only called when this image is not generated
  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. }< /p>
  14. error_page 404 403 402 500 502 503 504 /404.html;

  15. location = /404.html {
  16. }

  17. location ~ .php$ {

  18. fastcgi_pass 127.0 .0.1:9000;
  19. fastcgi_index index.php;
  20. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  21. includefastcgi_params;
  22. }

  23. }

Description , emphasize the article about browser caching, whether it is an image generated through php or an image generated using nginx cache, add a line in the php code

  1. header('Last-Modified: ' .gmdate('D, d M Y H:i:s') . ' GMT' );
Copying the code

is very helpful for using CDN. The http status code when the client accesses this file for the first time is 200. After refreshing, the status code is always 304. You understand the benefits. The local client caches it, saving bandwidth.



Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn