<?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 => " "
);
/**
* 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;
}
}
?>
|