Jul
7

Tạo ảnh thumnail trong CakePHP

Author admin    Category Chia sẻ     Tags , ,

Ứng dụng của bạn cho phép admin đăng hình, thông thường, bạn sẽ lưu trữ 2 dạng hình: hình thumb và hình kích thước thật. Tuy nhiên, trên layout website của bạn, hình hiển thị ở nhiều nơi với nhiều kích thước khác nhau, bạn không thể lường trước các size phải đáp ứng để có thể điều chỉnh code trong admin.

Bạn có thể dùng các thuộc tính width và height để “ép” size hình, làm như thế hình sẽ hiển thị không đẹp và dung lượng vẫn là dung lượng của hình gốc mặc dù size có nhỏ hơn.

Bài viết này sẽ hướng dẫn các bạn resize hình theo kích thước tùy ý trong khi chạy ứng dụng mà vẫn đảm bảo được chất lượng hình.

Đầu tiên, các bạn tạo một controller có tên là images_controller.php, đặt trong app/controllers

Nội dung file:

<?php
class ImagesController extends AppController {
 
  var $name = 'Images';
  var $uses = array();
 
  // variables
  var $cache_dir = 'img/cache';
  var $types = array(1 => "gif", "jpeg", "png", "swf", "psd", "wbmp", "jpg");
 
 
  /**
   * displays and resizes an image
   * @width 	= width to resize image to
   * @height 	= height to resize image to
   * @resize 	= true/false
   * @src 	= src dir of image from root
   */
  function view($width, $height, $noresize = 'resize') {
    // get params    
    $url = $this->_get_url($this->params['pass']);
 
    // get full image path
    $full_path = WWW_ROOT.$url;
 
    // check file exists
    if(file_exists($full_path)) {
      // get size of image
      $size	= getimagesize($full_path);
      // get mimetype
      $mime	= $size['mime'];
 
      // if either width or height is an asterix
      if($width == '*' || $height == '*') {
        if($height == '*') {
          // recalculate height
          $height = ceil($width / ($size[0]/$size[1]));
        } else {
          // recalculate width
          $width = ceil(($size[0]/$size[1]) * $height);
        }
      } else {
        if (($size[1]/$height) > ($size[0]/$width)) {
          $width = ceil(($size[0]/$size[1]) * $height);
        } else {
          $height = ceil($width / ($size[0]/$size[1]));
        }
      }
 
      // include folder in filename
      $dir_path = preg_replace("/[^a-z0-9_]/", "_", strtolower(dirname($url)));
      $dir_path .= '-'.basename($url);
 
      // create new file names
      $file_relative = $this->cache_dir.'/'.$width.'x'.$height.'_'.$dir_path;
      $file_cached = WWW_ROOT.$this->cache_dir.DS.$width.'x'.$height.'_'.$dir_path;
 
      // if cached file already exists
      if(file_exists($file_cached)) {
        // get image sizes
        $csize = getimagesize($file_cached);
        // check that cached file is correct dimensions
        $cached = ($csize[0] == $width && $csize[1] == $height);
        // check file age
        if (@filemtime($cachefile) < @filemtime($url))
          $cached = false;
      } else {
        $cached = false;
      }
 
      // if file not cached
      if(!$cached) {
        $resize = ($size[0] > $width || $size[1] > $height) || ($size[0] < $width || $size[1] < $height);
      } else {
        $resize = false;
      }
 
 
      // do not resize if set to true
      if($noresize == 'true') {
        $resize = false;
        $cached = false;
      }
 
      // if image resize is necessary
      if($resize) {
        // image
        $image = call_user_func('imagecreatefrom'.$this->types[$size[2]], $full_path);
        if (function_exists("imagecreatetruecolor") && ($temp = imagecreatetruecolor ($width, $height))) {
          imagecopyresampled ($temp, $image, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
        } else {
          $temp = imagecreate($width, $height);
          imagecopyresized($temp, $image, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
        }
        call_user_func("image".$this->types[$size[2]], $temp, $file_cached);
        imagedestroy($image);
        imagedestroy($temp);
      } elseif(!$cached) {
        // copy original file
        copy($full_path, $file_cached);
      }
 
      // get file contents
      $data	= file_get_contents($file_cached);
    } else {
      $size	= getimagesize($full_path);
      $mime	= $size['mime'];
      $data = file_get_contents($full_path);
    }
 
    // set headers and output image
    header("Content-type: $mime");
    header('Content-Length: ' . strlen($data));
    echo $data;
    exit();
  }
 
 
  /**
   * gets the url from the parameters
   */
  function _get_url($params) {
    // init
    $url = '';
    // unset unwanted params
    unset($params[0], $params[1], $params[2]);
    // loop through params
    foreach($params as $p) {
      $url .= $p.'/';
    }
    // remove last slash
    $url = substr($url, 0, strrpos($url, '/'));
    return $url;
  }
}
?>

Tiếp đến, bạn tạo thư mục cache trong app/webroot/img, chmod cho thư mục này là 777 nếu đưa lên host linux hoặc quyền write nếu đưa lên host windows.

Sử dụng:

<img src="<?php echo 'http://localhost/test_cake/images/view/140/90/resize/files/news/abc.jpg';?>" alt=""/>

Các bạn lưu ý là hàm view của controller Image nhận 3 tham số:

- Tham số 1: Chiều rộng hình cần tạo ra
- Tham số 2: Chiều cao hình cần tạo ra
- Tham số 3: Để true thì sẽ không resize

3 Comments to “Tạo ảnh thumnail trong CakePHP”

  • van tien 23/07/2010 at 3:07 pm

    Chào bạn!
    Trước tiên mình rất vui khi thấy bạn rất nhiệt tình chia sẽ kinh nghiệm với mọi người.Mình tham gia vào cộng đồng Cakephp chắc gần 1 năm rồi.Ngày trước mình học cũng theo yêu cầu thử việc của công ty,mình đã mất 2 tuần để học Cakephp.Và sau gần 1 năm khổ luyện mình cũng đã tích góp được một số kinh nghiệm kha khá.Ngày trước mình học chẳng có nỗi một cái gì gọi là ebook tiếng việt.Nên bây giờ bạn nào cần tư vấn về cakephp hãy pm mình qua spyke dn1it-18 (mình không có thời gian viết bài hướng dẫn Hi…).
    À quên cái code bạn viết trên dài dòng quá.Mình mạn phép sửa lại cái function resize()
    Ảnh thumbs bạn nên save thêm 1 cái khi upload cho tiện,mình sẽ cung cấp function resize() copy thêm 1 file (không làm hư ảnh gip,png trong suốt)

    */Thay đổi kích thước file (thumbs)
    Trong đó 
       $rFilefile gốc
       $w là độ rộng (để là auto nếu bạn muốn tự động co dãn chiều rộng)
      $h là chiều cao (để là auto nếu bạn muốn tự động co dãn chiều cao)
     // Lưu ý 2 biến $w,$h  chỉ có 1 biến được để auto
      $nFile là đường dẫn lưu file mới ví dụ file gốc là /images/sample.gif thì  thumbs $nFile/images/thumbs/sample.gif chẳng hạn 
    */
        function __resize($rFile,$w,$h,$nFile) {
            $imgInfo = getimagesize($rFile);
            switch ($imgInfo[2]) {
                case 1: $im = imagecreatefromgif($rFile);
                    break;
                case 3: $im = imagecreatefrompng($rFile);
                    break;
                default:  $im = imagecreatefromjpeg($rFile);
                    break;
            }
            if($h=='auto' &amp;&amp; is_numeric($w)) {
                $h=round(($w/$imgInfo[0]*100)*($imgInfo[1]/100));
            }
            if($w=='auto' &amp;&amp; is_numeric($h)) {
                $w=round(($h/$imgInfo[1]*100)*($imgInfo[0]/100));
            }
            $newImg = imagecreatetruecolor($w, $h);
            if(($imgInfo[2] == 1) OR ($imgInfo[2]==3)) {
                imagealphablending($newImg, false);
                imagesavealpha($newImg,true);
                $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
                imagefilledrectangle($newImg, 0, 0, $w, $h, $transparent);
            }
            imagecopyresampled($newImg, $im, 0, 0, 0, 0, $w, $h, $imgInfo[0], $imgInfo[1]);
            switch ($imgInfo[2]) {
                case 1: imagegif($newImg,$nFile);
                    break;
                case 3: imagepng($newImg,$nFile);
                    break;
                default:  imagejpeg($newImg,$nFile);
                    break;
            }
            return true;
        }

    Chúc may mắn

  • tung 01/11/2010 at 12:40 pm

    Trong Cakephp không có hàm tạo thumb nail như trong Codeignit hả anh

  • admin 03/11/2010 at 2:51 pm

    Không có, phải tự code hoặc chôm code làm của riêng cho mình thôi!

Post comment

Follow us on Twitter! Follow us on Twitter!
Diễn đàn CakePHP cho người Việt Nam

Bài viết mới

Thảo luận mới

TAG

Calendar

July 2010
M T W T F S S
« Jun   Aug »
 1234
567891011
12131415161718
19202122232425
262728293031  

Lưu trữ

Blogroll

Thống kê

6 khách