Changeset 10641


Ignore:
Timestamp:
Apr 27, 2011, 7:03:25 PM (13 years ago)
Author:
patdenice
Message:

feature:2284
Create a class to manipulate images.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/include/functions_upload.inc.php

    r10589 r10641  
    2323
    2424include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
     25include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
    2526
    2627// add default event handler for image and thumbnail resize
     
    363364    $high_infos = pwg_image_infos($high_path);
    364365   
    365     trigger_event(
    366       'upload_image_resize',
    367       false,
    368       $high_path,
     366    $img = new pwg_image($high_path);
     367
     368    $img->pwg_resize(
    369369      $file_path,
    370370      $conf['upload_form_websize_maxwidth'],
    371371      $conf['upload_form_websize_maxheight'],
    372372      $conf['upload_form_websize_quality'],
     373      $conf['upload_form_automatic_rotation'],
    373374      false
    374375      );
    375376
    376     if (is_imagick())
     377    if ($img->library != 'gd')
    377378    {
    378379      if ($conf['upload_form_hd_keep'])
     
    384385          if ($need_resize)
    385386          {
    386             pwg_image_resize(
    387               false,
    388               $high_path,
     387            $img->pwg_resize(
    389388              $high_path,
    390389              $conf['upload_form_hd_maxwidth'],
    391390              $conf['upload_form_hd_maxheight'],
    392391              $conf['upload_form_hd_quality'],
     392              $conf['upload_form_automatic_rotation'],
    393393              false
    394394              );
     
    403403      }
    404404    }
     405    $img->destroy();
    405406  }
    406407
     
    410411  $thumb_dir = dirname($thumb_path);
    411412  prepare_directory($thumb_dir);
    412  
    413   trigger_event(
    414     'upload_thumbnail_resize',
    415     false,
    416     $file_path,
     413
     414  $img = new pwg_image($file_path);
     415  $img->pwg_resize(
    417416    $thumb_path,
    418417    $conf['upload_form_thumb_maxwidth'],
    419418    $conf['upload_form_thumb_maxheight'],
    420419    $conf['upload_form_thumb_quality'],
    421     true,
    422     $conf['upload_form_thumb_crop'],
    423     $conf['upload_form_thumb_follow_orientation']
     420    $conf['upload_form_automatic_rotation'],
     421    true
    424422    );
     423  $img->destroy();
    425424 
    426425  $thumb_infos = pwg_image_infos($thumb_path);
     
    566565
    567566  return false;
    568 }
    569 
    570 function get_resize_dimensions($width, $height, $max_width, $max_height, $rotation=null)
    571 {
    572   $rotate_for_dimensions = false;
    573   if (isset($rotation) and in_array(abs($rotation), array(90, 270)))
    574   {
    575     $rotate_for_dimensions = true;
    576   }
    577 
    578   if ($rotate_for_dimensions)
    579   {
    580     list($width, $height) = array($height, $width);
    581   }
    582  
    583   $ratio_width  = $width / $max_width;
    584   $ratio_height = $height / $max_height;
    585   $destination_width = $width;
    586   $destination_height = $height;
    587  
    588   // maximal size exceeded ?
    589   if ($ratio_width > 1 or $ratio_height > 1)
    590   {
    591     if ($ratio_width < $ratio_height)
    592     {
    593       $destination_width = round($width / $ratio_height);
    594       $destination_height = $max_height;
    595     }
    596     else
    597     {
    598       $destination_width = $max_width;
    599       $destination_height = round($height / $ratio_width);
    600     }
    601   }
    602 
    603   if ($rotate_for_dimensions)
    604   {
    605     list($destination_width, $destination_height) = array($destination_height, $destination_width);
    606   }
    607  
    608   return array(
    609     'width' => $destination_width,
    610     'height'=> $destination_height,
    611     );
    612 }
    613 
    614 function pwg_image_resize($result, $source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata=false, $crop=false, $follow_orientation=true)
    615 {
    616   if ($result !== false)
    617   {
    618     //someone hooked us - so we skip
    619     return $result;
    620   }
    621 
    622   $extension = strtolower(get_extension($source_filepath));
    623 
    624   if (is_imagick() and $extension != 'gif')
    625   {
    626     return pwg_image_resize_im($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata, $crop, $follow_orientation);
    627   }
    628   else
    629   {
    630     return pwg_image_resize_gd($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $crop, $follow_orientation);
    631   }
    632 }
    633 
    634 function pwg_image_resize_gd($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $crop=false, $follow_orientation=true)
    635 {
    636   if (!function_exists('gd_info'))
    637   {
    638     return false;
    639   }
    640 
    641   $starttime = get_moment();
    642   $gd_info = gd_info();
    643 
    644   // extension of the picture filename
    645   $extension = strtolower(get_extension($source_filepath));
    646 
    647   $source_image = null;
    648   if (in_array($extension, array('jpg', 'jpeg')))
    649   {
    650     $source_image = imagecreatefromjpeg($source_filepath);
    651   }
    652   else if ($extension == 'png')
    653   {
    654     $source_image = imagecreatefrompng($source_filepath);
    655   }
    656   elseif ($extension == 'gif' and $gd_info['GIF Read Support'] and $gd_info['GIF Create Support'])
    657   {
    658     $source_image = imagecreatefromgif($source_filepath);
    659   }
    660   else
    661   {
    662     die('[GD] unsupported file extension');
    663   }
    664 
    665   $rotation = null;
    666   if (function_exists('imagerotate'))
    667   {
    668     $rotation = get_rotation_angle($source_filepath);
    669   }
    670  
    671   // width/height
    672   $source_width  = imagesx($source_image);
    673   $source_height = imagesy($source_image);
    674 
    675   // Crop
    676   if ($crop)
    677   {
    678     $coord = get_crop_coord($source_width, $source_height, $max_width, $max_height, $follow_orientation);
    679   }
    680 
    681   $resize_dimensions = get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation);
    682 
    683   // testing on height is useless in theory: if width is unchanged, there
    684   // should be no resize, because width/height ratio is not modified.
    685   if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height)
    686   {
    687     // the image doesn't need any resize! We just copy it to the destination
    688     copy($source_filepath, $destination_filepath);
    689     return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'GD');
    690   }
    691  
    692   $destination_image = imagecreatetruecolor($resize_dimensions['width'], $resize_dimensions['height']);
    693  
    694   imagecopyresampled(
    695     $destination_image,
    696     $source_image,
    697     0,
    698     0,
    699     $crop ? $coord['x'] : 0,
    700     $crop ? $coord['y'] : 0,
    701     $resize_dimensions['width'],
    702     $resize_dimensions['height'],
    703     $source_width,
    704     $source_height
    705     );
    706 
    707   // rotation occurs only on resized photo to avoid useless memory use
    708   if (isset($rotation))
    709   {
    710     $destination_image = imagerotate($destination_image, $rotation, 0);
    711   }
    712  
    713   $extension = strtolower(get_extension($destination_filepath));
    714   if ($extension == 'png')
    715   {
    716     imagepng($destination_image, $destination_filepath);
    717   }
    718   elseif ($extension == 'gif')
    719   {
    720     imagegif($destination_image, $destination_filepath);
    721   }
    722   else
    723   {
    724     imagejpeg($destination_image, $destination_filepath, $quality);
    725   }
    726   // freeing memory ressources
    727   imagedestroy($source_image);
    728   imagedestroy($destination_image);
    729 
    730   // everything should be OK if we are here!
    731   return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'GD');
    732 }
    733 
    734 function pwg_image_resize_im($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata=false, $crop=false, $follow_orientation=true)
    735 {
    736   $starttime = get_moment();
    737 
    738   // extension of the picture filename
    739   $extension = strtolower(get_extension($source_filepath));
    740   if (!in_array($extension, array('jpg', 'jpeg', 'png')))
    741   {
    742     die('[Imagick] unsupported file extension');
    743   }
    744 
    745   $image = new Imagick($source_filepath);
    746 
    747   $rotation = get_rotation_angle($source_filepath);
    748  
    749   // width/height
    750   $source_width  = $image->getImageWidth();
    751   $source_height = $image->getImageHeight();
    752 
    753   // Crop
    754   if ($crop)
    755   {
    756     $coord = get_crop_coord($source_width, $source_height, $max_width, $max_height, $follow_orientation);
    757     $image->cropImage($source_width, $source_height, $coord['x'], $coord['y']);
    758   }
    759  
    760   $resize_dimensions = get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation);
    761 
    762   // testing on height is useless in theory: if width is unchanged, there
    763   // should be no resize, because width/height ratio is not modified.
    764   if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height)
    765   {
    766     // the image doesn't need any resize! We just copy it to the destination
    767     copy($source_filepath, $destination_filepath);
    768     get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'ImageMagick');
    769   }
    770 
    771   $image->setImageCompressionQuality($quality);
    772   $image->setInterlaceScheme(Imagick::INTERLACE_LINE);
    773  
    774   if ($strip_metadata)
    775   {
    776     // we save a few kilobytes. For example a thumbnail with metadata
    777     // weights 25KB, without metadata 7KB.
    778     $image->stripImage();
    779   }
    780  
    781   $image->resizeImage($resize_dimensions['width'], $resize_dimensions['height'], Imagick::FILTER_LANCZOS, 0.9);
    782 
    783   if (isset($rotation))
    784   {
    785     $image->rotateImage(new ImagickPixel(), -$rotation);
    786     $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
    787   }
    788 
    789   $image->writeImage($destination_filepath);
    790   $image->destroy();
    791 
    792   // everything should be OK if we are here!
    793   return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'ImageMagick');
    794 }
    795 
    796 function get_rotation_angle($source_filepath)
    797 {
    798   global $conf;
    799 
    800   if (!$conf['upload_form_automatic_rotation'])
    801   {
    802     return null;
    803   }
    804 
    805   list($width, $height, $type) = getimagesize($source_filepath);
    806   if (IMAGETYPE_JPEG != $type)
    807   {
    808     return null;
    809   }
    810  
    811   if (!function_exists('exif_read_data'))
    812   {
    813     return null;
    814   }
    815 
    816   $rotation = null;
    817  
    818   $exif = exif_read_data($source_filepath);
    819  
    820   if (isset($exif['Orientation']) and preg_match('/^\s*(\d)/', $exif['Orientation'], $matches))
    821   {
    822     $orientation = $matches[1];
    823     if (in_array($orientation, array(3, 4)))
    824     {
    825       $rotation = 180;
    826     }
    827     elseif (in_array($orientation, array(5, 6)))
    828     {
    829       $rotation = 270;
    830     }
    831     elseif (in_array($orientation, array(7, 8)))
    832     {
    833       $rotation = 90;
    834     }
    835   }
    836 
    837   return $rotation;
    838 }
    839 
    840 function get_crop_coord(&$source_width, &$source_height, &$max_width, &$max_height, $follow_orientation)
    841 {
    842   $x = 0;
    843   $y = 0;
    844 
    845   if ($source_width < $source_height and $follow_orientation)
    846   {
    847     list($width, $height) = array($max_height, $max_width);
    848     $max_width = $width;
    849     $max_height = $height;
    850   }
    851 
    852   $img_ratio = $source_width / $source_height;
    853   $dest_ratio = $max_width / $max_height;
    854 
    855   if($dest_ratio > $img_ratio)
    856   {
    857     $destHeight = round($source_width * $max_height / $max_width);
    858     $y = round(($source_height - $destHeight) / 2 );
    859     $source_height = $destHeight;
    860   }
    861   elseif ($dest_ratio < $img_ratio)
    862   {
    863     $destWidth = round($source_height * $max_width / $max_height);
    864     $x = round(($source_width - $destWidth) / 2 );
    865     $source_width = $destWidth;
    866   }
    867 
    868   return array('x' => $x, 'y' => $y);
    869567}
    870568
     
    964662}
    965663
    966 function is_imagick()
    967 {
    968   if (class_exists('Imagick'))
    969   {
    970     return true;
    971   }
    972 
    973   return false;
    974 }
    975 
    976664function ready_for_upload_message()
    977665{
     
    1034722}
    1035723
    1036 function get_resize_result($source_filepath, $destination_filepath, $width, $height, $time, $library)
    1037 {
    1038   return array(
    1039     'source'      => $source_filepath,
    1040     'destination' => $destination_filepath,
    1041     'width'       => $width,
    1042     'height'      => $height,
    1043     'size'        => floor(filesize($destination_filepath) / 1024).' KB',
    1044     'time'            => number_format((get_moment() - $time) * 1000, 2, '.', ' ').' ms',
    1045     'library'     => $library,
    1046   );
    1047 }
    1048724?>
  • trunk/admin/photos_add.php

    r8728 r10641  
    2828include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
    2929include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
     30include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
    3031
    3132define(
  • trunk/admin/photos_add_settings.php

    r10589 r10641  
    112112    array(
    113113      'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL,
    114       'MANAGE_HD' => is_imagick(),
     114      'MANAGE_HD' => (pwg_image::is_imagick() or pwg_image::is_ext_imagick()),
    115115      'values' => $form_values
    116116    )
  • trunk/include/config_default.inc.php

    r10570 r10641  
    321321// 'filename'
    322322$conf['uniqueness_mode'] = 'md5sum';
     323
     324// Library used for image resizing. Value could be 'auto', 'imagick',
     325// 'ext_imagick or 'gd'. If value is 'auto', library will be choosen in this
     326// order. If choosen library is not available, another one will be picked up.
     327$conf['image_library'] = 'auto';
     328
     329// If library used is external installation of ImageMagick ('ext_imagick'),
     330// you can define imagemagick directory.
     331$conf['ext_imagick_dir'] = '';
    323332
    324333// +-----------------------------------------------------------------------+
  • trunk/include/ws_functions.inc.php

    r10596 r10641  
    26892689  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
    26902690  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
     2691  include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
    26912692
    26922693  if (!empty($params['image_id']))
     
    27262727    prepare_directory(dirname($thumb_path));
    27272728
    2728     $result = trigger_event(
    2729       'upload_thumbnail_resize',
    2730       false,
    2731       $image_path,
     2729    $img = new pwg_image($image_path, $params['library']);
     2730
     2731    $result =  $img->pwg_resize(
    27322732      $thumb_path,
    27332733      $params['maxwidth'],
    27342734      $params['maxheight'],
    27352735      $params['quality'],
     2736      $params['automatic_rotation'],
    27362737      true,
    27372738      get_boolean($params['crop']),
    27382739      get_boolean($params['follow_orientation'])
    27392740    );
     2741
     2742    $img->destroy();
    27402743  }
    27412744  elseif (file_exists($hd_path))
    27422745  {
    2743     $result = trigger_event(
    2744       'upload_image_resize',
    2745       false,
    2746       $hd_path,
     2746    $img = new pwg_image($hd_path);
     2747
     2748    $result = $img->pwg_resize(
    27472749      $image_path,
    27482750      $params['maxwidth'],
    27492751      $params['maxheight'],
    27502752      $params['quality'],
     2753      $params['automatic_rotation'],
    27512754      false
    27522755      );
     2756
     2757    $img->destroy();
    27532758
    27542759    if (!empty($image['has_high']))
  • trunk/ws.php

    r10563 r10641  
    412412      'image_path' => array('default' => null),
    413413      'type' => array('default' => 'thumbnail'),
     414      'automatic_rotation' => array('default' => $conf['upload_form_automatic_rotation']),
     415      'library' => array('default' => $conf['image_library']),
    414416      'maxwidth' => array('default' => null),
    415417      'maxheight' => array('default' => null),
Note: See TracChangeset for help on using the changeset viewer.