PHP Classes

File: ASCIIArtist.php

Recommend this page to a friend!
  Classes of Sebastian Röbke   Boosty's ASCII Artist   ASCIIArtist.php   Download  
File: ASCIIArtist.php
Role: Class source
Content type: text/plain
Description: ASCIIArtist class
Class: Boosty's ASCII Artist
Converts images into some kind of ASCII Art
Author: By
Last change: - Requires PHP >= 4.3.x
- Hopefully fixed remaining file access related bugs by simply using PHP >= 4.3.x file stream capabilities
- IMPORTANT! API changed for better error handling and cosmetical reasons, see updated example exe.php and included PHPDoc.
- Users of an older version need to update their custom frontends/scripts to use the new class version.
- Changed license to BSD
Date: 20 years ago
Size: 15,774 bytes
 

Contents

Class file image Download
<?php /** * ASCIIArtist - Class to convert Bitmap-Images into nice ASCII Texts in HTML format * * Copyright (c) 2004, Sebastian Röbke <sebastian@sebastian-r.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of Sebastian Röbke nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Credits: Florian Schäfer, Maxi Kellner, Andrea Spacca, Alastair Battrick * Requirements: PHP >= 4.3.x with GD support for the desired image format * * @author Sebastian Röbke <asciiartist@sebastian-r.de> * @version 1.4 * @link http://www.sebastian-r.de/asciiart/ * @package ASCIIArtist * @license BSD */ /** * ASCIIArtist class * * @package ASCIIArtist */ class ASCIIArtist { /** * The current class version * * @var string * @access private * @see getVersion() */ var $_version = "1.4"; /** * Array for error messages * * @var array * @access private * @see isError(), getErrors() */ var $_errors = array(); /** * The replace characters from dark to light used by render modes 0 and 1 * (current version can handle 9 variations) * * @var array * @access private */ var $_replaceCharacters = array ( 1 => "W", 2 => "@", 3 => "#", 4 => "*", 5 => "+", 6 => ":", 7 => ".", 8 => ",", 9 => "&nbsp;" ); /** * Possible image types * * @var array * @access private */ var $_imageTypes = array ( 1 => "gif", 2 => "jpeg", 3 => "png" ); /** * Image resource * * @var resource * @access private */ var $_image = 0; /** * Image file height * * @var integer * @access private */ var $_imageHeight = 0; /** * Image file height * * @var integer * @access private */ var $_imageWidth = 0; /** * Container for the rendered HTML/ASCII image * * @var string * @access private * @see getHTMLImage() */ var $_imageHTML = ''; /** * CSS for the HTML Image Output * * @var string * @access private * @see setImageCSS() */ var $_imageCSS = ' color : #000000; background-color : #FFFFFF; font-size : 8px; font-family : "Courier New", Courier, mono; line-height : 5px; letter-spacing : -1px; '; /** * CSS for the Error Output * * @var string * @access private * @see setErrorCSS() */ var $_errorCSS = ' text-align : center; color : #000000; background-color : #EFEFEF; font-size : 11px; font-family : Verdana, Arial, sans-serif; border-color : #333333; border-style : solid; border-width : 1px; margin : 4px; padding : 4px; '; /** * Var to remember the last font tag * * @var array * @access private */ var $_lastRGB = array(); /** * Var to remember the font tag state * * @var boolean * @access private */ var $_fontTagOpen = false; /** * Returns the hex string of a rgb array * * Example: * $rbg = array("red" -> 255, "green" -> 255, "blue" -> 255); * rgb2hex($rgb) will return "FFFFFF" * * @param array $rgb An array of red, green and blue values * @return string The hex values as one string * @access private */ function _RGB2HEX($rgb) { return sprintf("%02X%02X%02X",$rgb["red"],$rgb["green"],$rgb["blue"]); } /** * Renders the given pixel * * @param integer $mode Current version can handle mode 1, 2 or 3 * @param integer $x X Position of the image * @param integer $y Y Position of the image * @param string $fixedChar Needed for mode 3 * @access private */ function _renderPixel($mode, $x, $y, $fixedChar) { // RGB Value of current pixel (Array) $rgb = imagecolorsforindex($this->_image, imagecolorat($this->_image, $x, $y)); // Replace by mode switch ($mode) { case 1: // Rounded Brightness $brightness = $rgb["red"] + $rgb["green"] + $rgb["blue"]; // Choose replacing character $replaceCharacterNo = round($brightness / 100) + 1; $this->_imageHTML .= $this->_replaceCharacters[$replaceCharacterNo]; break; case 2: // Rounded Brightness $brightness = $rgb["red"] + $rgb["green"] + $rgb["blue"]; // Choose replacing character $replaceCharacterNo = round($brightness / 100) + 1; if ($this->_lastRGB == $rgb) { $this->_imageHTML .= $this->_replaceCharacters[$replaceCharacterNo]; } else { if ($this->_fontTagOpen) { $this->_imageHTML .= "</font>"; } $this->_imageHTML .= "<font color=\"#".$this->_RGB2HEX($rgb)."\">".$this->_replaceCharacters[$replaceCharacterNo]; $this->_fontTagOpen = true; } break; case 3: if ($this->_lastRGB == $rgb) { $this->_imageHTML .= $fixedChar; } else { if ($this->_fontTagOpen) { $this->_imageHTML .= "</font>"; } $this->_imageHTML .= "<font color=\"#".$this->_RGB2HEX($rgb)."\">".$fixedChar; $this->_fontTagOpen = true; } break; } $this->_lastRGB = $rgb; } /** * Returns the class version number * * @return string The class version number * @access public */ function getVersion () { return $this->_version; } /** * Formatting the HTML Image using CSS * * Tip: Use width-fixed fonts such as Courier only. * * @param string $css Stylesheet for the image * @access public */ function setImageCSS ($css) { $this->_imageCSS = $css; } /** * Formatting error messages using CSS * * @param string $css Stylesheet for error message * @access public */ function setErrorCSS ($css) { $this->_errorCSS = $css; } /** * Renders the image into HTML * * The following modes are implemented: * 1 = black/white using $replaceCharacters by brightness, * 2 = colourized using $replaceCharacters by brightness, * 3 = colourized using a fixed character definded by $fixedChar. * A resolution of 1 means that every pixel is being replaced, * whereas 5 for example means a scanned block of 5 pixel height and width, * resulting in less data to replace. * * @param integer $mode Current version can handle mode 1, 2 or 3 * @param integer $resolution Resolution for scanning the bitmap. * @param string $fixedChar Needed for mode 3 * @param boolean $flipH Flip output horizontally? * @param boolean $flipV Flip output vertically? * @access public * @see getHTMLImage() */ function renderHTMLImage($mode = 1, $resolution = 2, $fixedChar = 'W', $flipH = false, $flipV = false) { $this->_imageHTML = ''; // Minimum value for $resolution is 1 if ($resolution < 1) { $resolution = 1; } // Different loops for flipping if (!$flipH && !$flipV) { // Y-Axis for ($y = 0; $y < $this->_imageHeight; $y += $resolution) { // X-Axis for ($x = 0; $x < $this->_imageWidth; $x += $resolution) { $this->_renderPixel($mode, $x, $y, $fixedChar); } $this->_imageHTML .= "<br>\n"; } } else if ($flipH && !$flipV) { // Y-Axis for ($y = 0; $y < $this->_imageHeight; $y += $resolution) { // X-Axis for ($x = $this->_imageWidth; $x > 0; $x -= $resolution) { $this->_renderPixel($mode, $x, $y, $fixedChar); } $this->_imageHTML .= "<br>\n"; } } else if (!$flipH && $flipV) { // Y-Axis for ($y = $this->_imageHeight; $y > 0; $y -= $resolution) { // X-Axis for ($x = 0; $x < $this->_imageWidth; $x += $resolution) { $this->_renderPixel($mode, $x, $y, $fixedChar); } $this->_imageHTML .= "<br>\n"; } } else if ($flipH && $flipV) { // Y-Axis for ($y = $this->_imageHeight; $y > 0; $y -= $resolution) { // X-Axis for ($x = $this->_imageWidth; $x > 0; $x -= $resolution) { $this->_renderPixel($mode, $x, $y, $fixedChar); } $this->_imageHTML .= "<br>\n"; } } if ($this->_fontTagOpen) { $this->_imageHTML .= "</font>\n"; } } /** * Returns the rendered ASCII HTML image and CSS * * @return string The rendered HTML image and CSS * @access public */ function getHTMLImage() { return '<style type="text/css">' .'.asciiimage{' .$this->_imageCSS .'}</style>' .'<span class="asciiimage">' .$this->_imageHTML .'</span>'; } /** * Checks if an error has occured * * @return boolean * @access public * @see getErrors(), getHTMLErrors() */ function isError() { return count($this->_errors) > 0; } /** * Returns the unformatted error messages as an array * * @return array The error messages * @access public * @see isError() */ function getErrors() { return $this->_errors; } /** * Returns the error messages as HTML * * @return string The error messages as HTML * @access public * @see setErrorCSS() */ function getHTMLErrors() { if (!$this->isError()) { return ''; } $ret = '<style type="text/css">' .'.asciierror{' .$this->_errorCSS .'}</style>' .'<div class="asciierror">'; foreach($this->_errors as $error) { $ret.= '<b>Error:</b> '.htmlentities($error).'<br>'; } $ret.= '</div>'; return $ret; } /** * Tries to set the given bitmap image as source for the ASCII image * and determines width and height * * If $filename begins with "http://" (not case sensitive), an HTTP 1.0 connection * is opened to the specified server, the page is requested using the HTTP GET method. * If filename begins with "ftp://" (not case sensitive), an ftp connection to the * specified server is opened. * If the server does not support passive mode ftp, this will fail. * If filename is one of "php://stdin", "php://stdout", or "php://stderr", * the corresponding stdio stream will be opened. * If filename begins with anything else, the file will be opened from the filesystem. * * @param string $filename * @return boolean * @access public */ function setFile($filename) { if (!$imagesize = getimagesize($filename)) { $this->_errors[] = 'Cannot open "'.$filename.'" for reading.'; return false; } // Create Image from file by type, get and set size list($width,$height,$type) = $imagesize; switch ($type) { case 1: case 2: case 3: $imagefunction = "imagecreatefrom".$this->_imageTypes[$type]; if (!function_exists($imagefunction) || !$this->_image = $imagefunction($filename)) { $this->_errors[] = 'Unable to create images from '.$this->_imageTypes[$type].'. See http://de.php.net/manual/en/ref.image.php for more info.'; return false; } $this->_imageHeight = $height; $this->_imageWidth = $width; break; default: $this->_errors[] = 'Cannot determine image type of "'.$filename.'".'; return false; } return true; } /** * Returns the height of the original bitmap image in pixels * * @return integer * @access public */ function getImageHeight() { return $this->_imageHeight; } /** * Returns the width of the original bitmap image in pixels * * @return integer * @access public */ function getImageWidth() { return $this->_imageWidth; } } ?>