Skip to content

Instantly share code, notes, and snippets.

@Da-Fecto
Last active December 31, 2015 04:28
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Da-Fecto/7934045 to your computer and use it in GitHub Desktop.
Module to caculate max imagesize it could take in a box.
<?php
/**
* ProcessWire 'Image Fit Boundaries' module
*
* Module to calculate the max size a image can take in a boundary box.
* © Martijn Geerts 2013
*
* Usage:
*
* $image = $page->image; // image from $page, or any other ProcessWire image
*
* // $x & $y are required
* $x = 200; // width, the size of the box (max width an image can scale in width)
* $y = 100; // height, the size of the box (max height an image can scale in height)
*
* // $compress is optional
* $compress = 30; // Makes heavier images procentual smaller then normal images, from (low) 1 to (high) 99 compression
*
* // usage 1
* $img = $modules->get("ImageFitBoundaries");
* $img = $img->load($image, $x, $y, $compress);
* echo $img->render();
*
* // usage 2
* $mod = $modules->get("ImageFitBoundaries");
* $info = $mod->load($image, $x, $y, $compress)->info();
* $thumb = $image->size($info['width'], $info['height']);
* echo "<img src='$thumb->url'>";
*
* ------------------------------------------------------
*
* ProcessWire 2.x
* Copyright (C) 2010 by Ryan Cramer
* Licensed under GNU/GPL v2, see LICENSE.TXT
*
* http://www.processwire.com
* http://www.ryancramer.com
*
*/
class ImageFitBoundaries extends WireData implements Module {
// internal check to protect public methodes 'render' & 'info'
protected $initialized = false;
protected $settings = array(
'image' => null,
'box_x' => null,
'box_y' => null,
'new_size' => array(),
'compress' => null,
);
/**
* Tell ProcessWire about this module
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => 'ImageFitBoundaries',
'version' => 001,
'summary' => __('Give in a box-size & and and Pageimage and it wil caculate the max image size the image can be.'),
'href' => 'http://www.processwire.com',
'singular' => false,
'autoload' => false,
);
}
/**
* Initialize the module, needed for ProcessWire
*
*/
public function init() {}
/**
* Load a Pageimage and settings
* @param Pageimage $image $images to calculate the new size for
* @param (int) $box_x The width of the box, max width an image can take.
* @param (int) $box_y The height of the box, max height an image can take.
* @param (int) $proc from 1 till 99
* @return $this For chaining only
*/
public function load( Pageimage $image, $box_x = 0, $box_y = 0, $proc = 0) {
// return if no box-size given
if(!$box_x && !$box_y) return false;
// here to protect public 'render' & 'info'
$this->initialized = true;
// should we shrink ?
$shrinkIt = (int) $proc > 0 && (int) $proc < 100 ? (int) round($proc) : null;
// set settings
$this->settings['image'] = $image;
$this->settings['box_x'] = (int) $box_x;
$this->settings['box_y'] = (int) $box_y;
$this->settings['compress'] = $shrinkIt;
// calculate the new sizes & set value in $settings array
$this->calculateSize();
//
if ($shrinkIt) $this->shrinkIt();
return $this;
}
/**
* Calculate new image size depending on box size
*
* @return (array) Array with width & height
*/
protected function calculateSize() {
// Related to Pageimage
$image = $this->settings['image'];
// calculate ratio beween image & wanted size
$rX = $this->settings['box_x'] / $image->width;
$rY = $this->settings['box_y'] / $image->height;
// the least expensive, is taken for size caculation
$width = min($rX, $rY) * $image->width;
$height = min($rX, $rY) * $image->height;
// set new_size settings, array with width/height
$size = array('width' => $width, 'height' => $height);
// cache it in the module
$this->settings['new_size'] = $size;
$this->info = $size;
return $this;
}
/**
* Resize the resized sizes, depending on squared size of box.
*
*/
protected function shrinkIt() {
$i = 0;
$array = array();
$range = range(0, 100); // create array
$compress = $this->settings['compress'];
$fraction = $compress / 100;
$width = $this->settings['new_size']['width'];
$height = $this->settings['new_size']['height'];
// key of array, will be used by percentage value
foreach ($range as $key) {
$array[$key] = $i;
$i = $i + $fraction;
}
// procent compare to box
$proc = (int) ( $width * $height ) * 100 / ( $this->settings['box_x'] * $this->settings['box_y'] );
$this->settings['new_size']['width'] = round($width - ($array[$proc] * $width / 100));
$this->settings['new_size']['height'] = round($height - ($array[$proc] * $height / 100));
// set the $info
$this->info = $this->settings['new_size'];
return $this;
}
/**
* Returns Markup for newly created image.
*
* @return (string) <img src='...
*/
public function render() {
// can't render when load is not called or data is insufficient.
if(!$this->initialized) return $this->_("Only accessible if all data provided in the load methode.");
// grab image
$image = $this->settings['image'];
// get new sizes (array)
$size = $this->settings['new_size'];
$width = $size['width'];
$height = $size['height'];
// create thumbnail
$thumb = $image->size($width, $height);
return "<img src='$thumb->url' alt='$thumb->description' width='$width' height='$height'>";
}
/**
* Returns an array containing with width & height info
*
* @return (array) array('width' => ... , 'height' => ... );
*/
public function info() {
// can't render when load is not called or data is insufficient.
if(!$this->initialized) return $this->_("Only accessible if all data provided in the load methode.");
// return size array
return $this->settings['new_size'];
}
/**
* Same as info methode, here for convenience
*
* @return (array) array('width' => ... , 'height' => ... );
*/
public $info = array();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment