To participate you must create an account on apostrophenow.org. If you have already done so, click Login.

Show
Ignore:
Timestamp:
08/08/10 12:18:34 (22 months ago)
Author:
tboutell
Message:

Merged the cropping branch back to trunk:

Cropping is now available in the media repository. Every time you select an image for use on the site you have the opportunity to crop it. The image size constraints of the slot are taken into account. This means that you can satisfy a given set of constraints by cropping a wide variety of images that would not have been eligible for selection before.

Crops of existing images appear in the database as separate aMediaItem objects but do not duplicate the original image file. This means that many crops of a single source image can exist without significant overhead.

The slug field of a cropped version of an image contains cropping parameters. When rendering the image, Symfony routes spot these and crop the original file as needed.

By approaching the problem this way we have avoided the need for code that takes advantage of the media repository's image selection capabilities to change in any way in order to take advantage of cropping.

The single-image-select behavior of Apostrophe has changed to accommodate the extra cropping step. Single select for PDFs and videos still uses the selectSingle partial because they cannot be cropped.

Thanks to Spike Broehm for his contributions to the cropping project.

Fixes #227

Location:
plugins/apostrophePlugin/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • plugins/apostrophePlugin/trunk

  • plugins/apostrophePlugin/trunk/lib/toolkit/aMediaTools.php

    r883 r1917  
    33class aMediaTools 
    44{ 
    5   // These are used internally. If you want to select something 
    6   // with the media module please see the README, do not use these  
    7   // methods directly 
     5  // These are used internally. See aMediaSelect for the methods you probably want 
    86 
    97  static public function setSelecting($after, $multiple, $selection,  
    108    $options = array()) 
    119  { 
     10    $items = aMediaItemTable::retrieveByIds($selection); 
     11    $ids = array(); 
     12    $imageInfo = array(); 
     13    $selection = array(); 
     14    foreach ($items as $item) 
     15    { 
     16      $croppingInfo = array(); 
     17      if ($item->isCrop()) 
     18      { 
     19        $croppingInfo = $item->getCroppingInfo(); 
     20        $item = $item->getCropOriginal(); 
     21      } 
     22      $id = $item->id; 
     23      $selection[] = $id; 
     24      $info = array('width' => $item->width, 'height' => $item->height); 
     25      $info = array_merge($info, $croppingInfo); 
     26      $imageInfo[$item->id] = $info; 
     27    } 
     28     
     29    $cropping = isset($options['cropping']) && $options['cropping']; 
     30 
    1231    self::clearSelecting(); 
    1332    self::setAttribute("selecting", true); 
    1433    self::setAttribute("after", $after); 
    1534    self::setAttribute("multiple", $multiple); 
     35    self::setAttribute("cropping", $cropping); 
    1636    self::setAttribute("selection", $selection); 
     37    self::setAttribute("imageInfo", $imageInfo); 
    1738    foreach ($options as $key => $val) 
    1839    { 
     
    140161    "selected_constraints" => array( 
    141162        "width" => 100, 
    142         "height" => 75, 
    143         "resizeType" => "c"), 
     163        "height" => false, 
     164        "resizeType" => "c",), 
    144165    "show_constraints" => array( 
    145166        "width" => 720, 
    146167        "height" => false, 
     168        "resizeType" => "s"), 
     169    "crop_constraints" => array( 
     170        "width" => 679, 
     171        "height" => 400, 
    147172        "resizeType" => "s"), 
    148173    'routes_register' => true, 
     
    188213    return $item; 
    189214  } 
     215   
     216  // refactored this into this static method from executeMultipleList() because it is now needed 
     217  // for executeUpdateMultiplePreview() for cropping slideshow items 
     218  static public function getSelectedItems() 
     219  { 
     220    $selection = self::getSelection(); 
     221    if (!is_array($selection)) 
     222    { 
     223      throw new Exception("selection is not an array"); 
     224    } 
     225    // Work around the fact that whereIn doesn't evaluate to AND FALSE 
     226    // when the array is empty (it just does nothing; which is an 
     227    // interesting variation on MySQL giving you an ERROR when the  
     228    // list is empty, sigh) 
     229    if (count($selection)) 
     230    { 
     231      // Work around the unsorted results of whereIn. You can also 
     232      // do that with a FIELD function 
     233      $unsortedItems = Doctrine_Query::create()-> 
     234        from('aMediaItem i')-> 
     235        whereIn('i.id', $selection)-> 
     236        execute(); 
     237      $itemsById = array(); 
     238      foreach ($unsortedItems as $item) 
     239      { 
     240        $itemsById[$item->getId()] = $item; 
     241      } 
     242      $items = array(); 
     243      foreach ($selection as $id) 
     244      { 
     245        if (isset($itemsById[$id])) 
     246        { 
     247          $items[] = $itemsById[$id]; 
     248        } 
     249      } 
     250    } 
     251    else 
     252    { 
     253      $items = array(); 
     254    } 
     255     
     256    return $items; 
     257  } 
     258   
     259  static public function getAspectRatio() 
     260  { 
     261    if (self::getAttribute('aspect-width') && self::getAttribute('aspect-width')) 
     262    { 
     263      return self::getAttribute('aspect-width') / self::getAttribute('aspect-height'); 
     264    } 
     265    return 0; 
     266  } 
     267   
     268  static public function getSelectedThumbnailHeight() 
     269  { 
     270    $selectedConstraints = self::getOption('selected_constraints'); 
     271    if (false === $selectedConstraints['height']) 
     272    { 
     273      if ($aspectRatio = self::getAspectRatio()) 
     274      { 
     275        return $selectedConstraints['width'] / $aspectRatio; 
     276      } 
     277      return 0; // Let's not divide by zero. 
     278    } 
     279    return $selectedConstraints['height']; 
     280  } 
     281   
     282  /** 
     283   * This mirrors the default size math in aCrop.setAspectMask() in aCrop.js 
     284   */ 
     285  static public function setDefaultCropDimensions($mediaItem) 
     286  { 
     287    $imageInfo = self::getAttribute('imageInfo'); 
     288    $aspectRatio = self::getAspectRatio(); 
     289     
     290    if ($aspectRatio) 
     291    {     
     292      if ($aspectRatio > 1) 
     293      { 
     294        $imageInfo[$mediaItem->id]['cropWidth'] = $mediaItem->getWidth(); 
     295        $imageInfo[$mediaItem->id]['cropHeight'] = floor($mediaItem->getWidth() / $aspectRatio); 
     296      } 
     297      else 
     298      { 
     299        $imageInfo[$mediaItem->id]['cropHeight'] = $mediaItem->getHeight(); 
     300        $imageInfo[$mediaItem->id]['cropWidth'] = floor($mediaItem->getHeight() * $aspectRatio); 
     301      } 
     302    } 
     303    else 
     304    { 
     305      $imageInfo[$mediaItem->id]['cropWidth'] = $mediaItem->getWidth(); 
     306      $imageInfo[$mediaItem->id]['cropHeight'] = $mediaItem->getHeight(); 
     307    } 
     308     
     309    $imageInfo[$mediaItem->id]['cropLeft'] = 0; 
     310    $imageInfo[$mediaItem->id]['cropTop'] = floor(($mediaItem->getHeight() - $imageInfo[$mediaItem->id]['cropHeight']) / 2); 
     311         
     312    self::setAttribute('imageInfo', $imageInfo); 
     313  } 
    190314}