diff options
Diffstat (limited to 'platform/www/lib/plugins/farmer/3rdparty')
-rw-r--r-- | platform/www/lib/plugins/farmer/3rdparty/PHPIco.php | 248 | ||||
-rw-r--r-- | platform/www/lib/plugins/farmer/3rdparty/RingIcon.php | 186 |
2 files changed, 434 insertions, 0 deletions
diff --git a/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php b/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php new file mode 100644 index 0000000..17b3b55 --- /dev/null +++ b/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php @@ -0,0 +1,248 @@ +<?php +/* +Copyright 2011-2013 Chris Jean & iThemes +Licensed under GPLv2 or above + +Version 1.0.2 + +Adjusted for DokuWiki Farmer Plugin +*/ + +namespace chrisbliss18\phpico; + +class PHPIco { + /** + * Images in the BMP format. + * + * @var array + * @access private + */ + var $_images = array(); + + /** + * Constructor - Create a new ICO generator. + * + * If the constructor is not passed a file, a file will need to be supplied using the {@link PHP_ICO::add_image} + * function in order to generate an ICO file. + * + * @param bool|string $file Optional. Path to the source image file. + * @param array $sizes Optional. An array of sizes (each size is an array with a width and height) that the source image should be rendered at in the generated ICO file. If sizes are not supplied, the size of the source image will be used. + * @throws \Exception + */ + function __construct( $file = false, $sizes = array() ) { + $required_functions = array( + 'getimagesize', + 'imagecreatefromstring', + 'imagecreatetruecolor', + 'imagecolortransparent', + 'imagecolorallocatealpha', + 'imagealphablending', + 'imagesavealpha', + 'imagesx', + 'imagesy', + 'imagecopyresampled', + ); + + foreach ( $required_functions as $function ) { + if ( ! function_exists( $function ) ) { + throw new \Exception( "The PHP_ICO class was unable to find the $function function, which is part of the GD library. Ensure that the system has the GD library installed and that PHP has access to it through a PHP interface, such as PHP's GD module. Since this function was not found, the library will be unable to create ICO files." ); + } + } + + if ( false != $file ) + $this->add_image( $file, $sizes ); + } + + /** + * Add an image to the generator. + * + * This function adds a source image to the generator. It serves two main purposes: add a source image if one was + * not supplied to the constructor and to add additional source images so that different images can be supplied for + * different sized images in the resulting ICO file. For instance, a small source image can be used for the small + * resolutions while a larger source image can be used for large resolutions. + * + * @param string $file Path to the source image file. + * @param array $sizes Optional. An array of sizes (each size is an array with a width and height) that the source image should be rendered at in the generated ICO file. If sizes are not supplied, the size of the source image will be used. + * @return boolean true on success and false on failure. + */ + function add_image( $file, $sizes = array() ) { + if ( false === ( $im = $this->_load_image_file( $file ) ) ) + return false; + + + if ( empty( $sizes ) ) + $sizes = array( imagesx( $im ), imagesy( $im ) ); + + // If just a single size was passed, put it in array. + if ( ! is_array( $sizes[0] ) ) + $sizes = array( $sizes ); + + foreach ( (array) $sizes as $size ) { + list( $width, $height ) = $size; + + $new_im = imagecreatetruecolor( $width, $height ); + + imagecolortransparent( $new_im, imagecolorallocatealpha( $new_im, 0, 0, 0, 127 ) ); + imagealphablending( $new_im, false ); + imagesavealpha( $new_im, true ); + + $source_width = imagesx( $im ); + $source_height = imagesy( $im ); + + if ( false === imagecopyresampled( $new_im, $im, 0, 0, 0, 0, $width, $height, $source_width, $source_height ) ) + continue; + + $this->_add_image_data( $new_im ); + } + + return true; + } + + /** + * Write the ICO file data to a file path. + * + * @param string $file Path to save the ICO file data into. + * @return boolean true on success and false on failure. + */ + function save_ico( $file ) { + if ( false === ( $data = $this->_get_ico_data() ) ) + return false; + + if ( false === ( $fh = fopen( $file, 'w' ) ) ) + return false; + + if ( false === ( fwrite( $fh, $data ) ) ) { + fclose( $fh ); + return false; + } + + fclose( $fh ); + + return true; + } + + /** + * Generate the final ICO data by creating a file header and adding the image data. + */ + protected function _get_ico_data() { + if ( ! is_array( $this->_images ) || empty( $this->_images ) ) + return false; + + + $data = pack( 'vvv', 0, 1, count( $this->_images ) ); + $pixel_data = ''; + + $icon_dir_entry_size = 16; + + $offset = 6 + ( $icon_dir_entry_size * count( $this->_images ) ); + + foreach ( $this->_images as $image ) { + $data .= pack( 'CCCCvvVV', $image['width'], $image['height'], $image['color_palette_colors'], 0, 1, $image['bits_per_pixel'], $image['size'], $offset ); + $pixel_data .= $image['data']; + + $offset += $image['size']; + } + + $data .= $pixel_data; + unset( $pixel_data ); + + + return $data; + } + + /** + * Take a GD image resource and change it into a raw BMP format. + * + * @param resource $im + */ + protected function _add_image_data( $im ) { + $width = imagesx( $im ); + $height = imagesy( $im ); + + + $pixel_data = array(); + + $opacity_data = array(); + $current_opacity_val = 0; + + for ( $y = $height - 1; $y >= 0; $y-- ) { + for ( $x = 0; $x < $width; $x++ ) { + $color = imagecolorat( $im, $x, $y ); + + $alpha = ( $color & 0x7F000000 ) >> 24; + $alpha = ( 1 - ( $alpha / 127 ) ) * 255; + + $color &= 0xFFFFFF; + $color |= 0xFF000000 & ( $alpha << 24 ); + + $pixel_data[] = $color; + + + $opacity = ( $alpha <= 127 ) ? 1 : 0; + + $current_opacity_val = ( $current_opacity_val << 1 ) | $opacity; + + if ( ( ( $x + 1 ) % 32 ) == 0 ) { + $opacity_data[] = $current_opacity_val; + $current_opacity_val = 0; + } + } + + if ( ( $x % 32 ) > 0 ) { + while ( ( $x++ % 32 ) > 0 ) + $current_opacity_val = $current_opacity_val << 1; + + $opacity_data[] = $current_opacity_val; + $current_opacity_val = 0; + } + } + + $image_header_size = 40; + $color_mask_size = $width * $height * 4; + $opacity_mask_size = ( ceil( $width / 32 ) * 4 ) * $height; + + + $data = pack( 'VVVvvVVVVVV', 40, $width, ( $height * 2 ), 1, 32, 0, 0, 0, 0, 0, 0 ); + + foreach ( $pixel_data as $color ) + $data .= pack( 'V', $color ); + + foreach ( $opacity_data as $opacity ) + $data .= pack( 'N', $opacity ); + + + $image = array( + 'width' => $width, + 'height' => $height, + 'color_palette_colors' => 0, + 'bits_per_pixel' => 32, + 'size' => $image_header_size + $color_mask_size + $opacity_mask_size, + 'data' => $data, + ); + + $this->_images[] = $image; + } + + /** + * Read in the source image file and convert it into a GD image resource. + * + * @param string $file + * @return bool|resource + */ + protected function _load_image_file( $file ) { + // Run a cheap check to verify that it is an image file. + if ( false === ( $size = getimagesize( $file ) ) ) + return false; + + if ( false === ( $file_data = file_get_contents( $file ) ) ) + return false; + + if ( false === ( $im = imagecreatefromstring( $file_data ) ) ) + return false; + + unset( $file_data ); + + + return $im; + } +} diff --git a/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php b/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php new file mode 100644 index 0000000..c8dfdbc --- /dev/null +++ b/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php @@ -0,0 +1,186 @@ +<?php + +namespace splitbrain\RingIcon; + +/** + * Class RingIcon + * + * Generates a identicon/visiglyph like image based on concentric rings + * + * @todo add a mono color version + * @author Andreas Gohr <andi@splitbrain.org> + * @license MIT + * @package splitbrain\RingIcon + */ +class RingIcon +{ + + protected $size; + protected $fullsize; + protected $rings; + protected $center; + protected $ringwidth; + protected $seed; + protected $ismono = false; + protected $monocolor = null; + + /** + * RingIcon constructor. + * @param int $size width and height of the resulting image + * @param int $rings number of rings + */ + public function __construct($size, $rings = 3) + { + $this->size = $size; + $this->fullsize = $this->size * 5; + $this->rings = 4; + + $this->center = floor($this->fullsize / 2); + $this->ringwidth = floor($this->fullsize / $rings); + + $this->seed = mt_rand() . time(); + } + + /** + * Generates an ring image + * + * If a seed is given, the image will be based on that seed + * + * @param string $seed initialize the genrator with this string + * @param string $file if given, the image is saved at that path, otherwise is printed to browser + */ + public function createImage($seed = '', $file = '') + { + if (!$seed) { + $seed = mt_rand() . time(); + } + $this->seed = $seed; + + // monochrome wanted? + if($this->ismono) { + $this->monocolor = array( + $this->rand(20,255), + $this->rand(20,255), + $this->rand(20,255) + ); + } else { + $this->monocolor = null; + } + + // create + $image = $this->createTransparentImage($this->fullsize, $this->fullsize); + $arcwidth = $this->fullsize; + for ($i = $this->rings; $i > 0; $i--) { + $this->drawRing($image, $arcwidth); + $arcwidth -= $this->ringwidth; + } + + // resample for antialiasing + $out = $this->createTransparentImage($this->size, $this->size); + imagecopyresampled($out, $image, 0, 0, 0, 0, $this->size, $this->size, $this->fullsize, $this->fullsize); + if ($file) { + imagepng($out, $file); + } else { + header("Content-type: image/png"); + imagepng($out); + } + imagedestroy($out); + imagedestroy($image); + } + + /** + * When set to true a monochrome version is returned + * + * @param bool $ismono + */ + public function setMono($ismono) { + $this->ismono = $ismono; + } + + /** + * Generate number from seed + * + * Each call runs MD5 on the seed again + * + * @param int $min + * @param int $max + * @return int + */ + protected function rand($min, $max) + { + $this->seed = md5($this->seed); + $rand = hexdec(substr($this->seed, 0, 8)); + return ($rand % ($max - $min + 1)) + $min; + } + + /** + * Drawas a single ring + * + * @param resource $image + * @param int $arcwidth outer width of the ring + */ + protected function drawRing($image, $arcwidth) + { + $color = $this->randomColor($image); + $transparency = $this->transparentColor($image); + + $start = $this->rand(20, 360); + $stop = $this->rand(20, 360); + if($stop < $start) list($start, $stop) = array($stop, $start); + + imagefilledarc($image, $this->center, $this->center, $arcwidth, $arcwidth, $stop, $start, $color, IMG_ARC_PIE); + imagefilledellipse($image, $this->center, $this->center, $arcwidth - $this->ringwidth, + $arcwidth - $this->ringwidth, $transparency); + + imagecolordeallocate($image, $color); + imagecolordeallocate($image, $transparency); + } + + /** + * Allocate a transparent color + * + * @param resource $image + * @return int + */ + protected function transparentColor($image) + { + return imagecolorallocatealpha($image, 0, 0, 0, 127); + } + + /** + * Allocate a random color + * + * @param $image + * @return int + */ + protected function randomColor($image) + { + if($this->ismono) { + return imagecolorallocatealpha($image, $this->monocolor[0], $this->monocolor[1], $this->monocolor[2], $this->rand(0, 96)); + } + return imagecolorallocate($image, $this->rand(0, 255), $this->rand(0, 255), $this->rand(0, 255)); + } + + /** + * Create a transparent image + * + * @param int $width + * @param int $height + * @return resource + * @throws \Exception + */ + protected function createTransparentImage($width, $height) + { + $image = @imagecreatetruecolor($width, $height); + if (!$image) { + throw new \Exception('Missing libgd support'); + } + imagealphablending($image, false); + $transparency = $this->transparentColor($image); + imagefill($image, 0, 0, $transparency); + imagecolordeallocate($image, $transparency); + imagesavealpha($image, true); + return $image; + } + +} |