1<?php 2 3define('IMAGE_3D_DRIVER_ASCII_GRAY', 0.01); 4 5class Image_3D_Driver_ASCII extends Image_3D_Driver 6{ 7 8 protected $_size; 9 protected $_filetype; 10 protected $_points; 11 protected $_heigth; 12 protected $_image; 13 14 protected $_charArray = array( 15 0 => ' ', 16 1 => '`', 17 2 => '\'', 18 3 => '^', 19 4 => '-', 20 5 => '`', 21 6 => '/', 22 7 => '/', 23 8 => '-', 24 9 => '\\', 25 10 => '\'', 26 11 => '\\', 27 12 => '~', 28 13 => '+', 29 14 => '+', 30 15 => '*', 31 16 => '.', 32 17 => '|', 33 18 => '/', 34 19 => '/', 35 20 => '|', 36 21 => '|', 37 22 => '/', 38 23 => '/', 39 24 => '/', 40 25 => ')', 41 26 => '/', 42 27 => 'Y', 43 28 => 'r', 44 29 => '}', 45 30 => '/', 46 31 => 'P', 47 32 => '.', 48 33 => '\\', 49 34 => '|', 50 35 => '^', 51 36 => '\\', 52 37 => '\\', 53 38 => '(', 54 39 => '(', 55 40 => ':', 56 41 => '\\', 57 42 => '|', 58 43 => 'I', 59 44 => ';', 60 45 => '\\', 61 46 => '{', 62 47 => '9', 63 48 => '_', 64 49 => '_', 65 50 => '_', 66 51 => 'C', 67 52 => '<', 68 53 => 'L', 69 54 => 'l', 70 55 => 'C', 71 56 => '>', 72 57 => 'J', 73 58 => 'J', 74 59 => 'J', 75 60 => 'o', 76 61 => 'b', 77 62 => 'd', 78 63 => '#', 79 ); 80 81 public function __construct() 82 { 83 parent::__construct(); 84 $this->_filetype = 'txt'; 85 86 $this->reset(); 87 } 88 89 public function reset() 90 { 91 $this->_points = array(); 92 $this->_heigth = array(); 93 94 $this->_image = array(); 95 } 96 97 public function createImage($x, $y) 98 { 99 $this->_size = array($x, $y); 100 } 101 102 protected function _getColor(Image_3D_Color $color, $alpha = 1.) 103 { 104 $values = $color->getValues(); 105 return array($values[0], $values[1], $values[2], (1 - $values[3]) * $alpha); 106 } 107 108 protected function _mixColor($old, $new) 109 { 110 $faktor = (1 - $new[3]) * $old[3]; // slight speed improvement 111 return array( 112 $old[0] * $faktor + $new[0] * $new[3], 113 $old[1] * $faktor + $new[1] * $new[3], 114 $old[2] * $faktor + $new[2] * $new[3], 115 $old[3] * $old[3] + $new[3] 116 ); 117 118 } 119 120 public function setBackground(Image_3D_Color $color) 121 { 122 $bg = $this->_getColor($color); 123 124 for ($x = 0; $x < $this->_size[0]; ++$x) { 125 for ($y = 0; $y < $this->_size[1]; ++$y) { 126 $this->_image[$x][$y] = $bg; 127 } 128 } 129 } 130 131 protected function _drawLine(Image_3D_Point $p1, Image_3D_Point $p2) 132 { 133 list($x1, $y1) = $p1->getScreenCoordinates(); 134 list($x2, $y2) = $p2->getScreenCoordinates(); 135 136 $steps = ceil(max(abs($x1 - $x2), abs($y1 - $y2))); 137 138 $xdiff = ($x2 - $x1) / $steps; 139 $ydiff = ($y2 - $y1) / $steps; 140 141 $points = array(); 142 for ($i = 0; $i < $steps; ++$i) { 143 $points[(int) round($x1 + $i * $xdiff)][(int) round($y1 + $i * $ydiff)] = true; 144 } 145 return $points; 146 } 147 148 protected function _getPolygonOutlines($pointArray) 149 { 150 $map = array(); 151 152 $last = end($pointArray); 153 foreach ($pointArray as $point) { 154 $line = $this->_drawLine($last, $point); 155 $last = $point; 156 // Merge line to map 157 foreach ($line as $x => $row) { 158 foreach ($row as $y => $height) { 159 $map[(int) $x][(int) $y] = $height; 160 } 161 } 162 } 163 164 return $map; 165 } 166 167 public function drawPolygon(Image_3D_Polygon $polygon) 168 { 169 $points = $this->_getPolygonOutlines($polygon->getPoints()); 170 171 foreach ($points as $x => $row) { 172 if (count($row) < 2) { 173 continue; 174 } 175 176 $start = min(array_keys($row)); 177 $end = max(array_keys($row)); 178 179 // Starting point 180 $this->_heigth[$x][$start] = $this->_getColor($polygon->getColor()); 181 182 // the way between 183 for ($y = $start + 1; $y < $end; ++$y) { 184 $this->_heigth[$x][$y] = $this->_getColor($polygon->getColor()); 185 } 186 187 // Ending point 188 $this->_points[$x][$end] = $this->_getColor($polygon->getColor()); 189 } 190 } 191 192 public function drawGradientPolygon(Image_3D_Polygon $polygon) 193 { 194 $this->drawPolygon($polygon); 195 } 196 197 public function setFiletye($type) 198 { 199 $type = strtolower($type); 200 if (in_array($type, array('png', 'jpeg'))) { 201 $this->_filetype = $type; 202 return true; 203 } else { 204 return false; 205 } 206 } 207 208 public function _getAnsiColorCode($color, $last = '') 209 { 210 $code = "\033[0;" . (30 + bindec((int) round($color[2]) . (int) round($color[1]) . (int) round($color[0]))) . 'm'; 211 if ($last !== $code) { 212 return $code; 213 } 214 return ''; 215 } 216 217 public function save($file) 218 { 219 220 $asciiWidth = (int) ceil($this->_size[0] / 2); 221 $asciiHeight = (int) ceil($this->_size[1] / 6); 222 223 $output = "\033[2J"; 224 $lastColor = ''; 225 226 for ($y = 0; $y < $asciiHeight; ++$y) { 227 for ($x = 0; $x < $asciiWidth; ++$x) { 228 // Get pixelarray 229 $char = 0; 230 231 $charColor = array(0, 0, 0); 232 for ($xi = 0; $xi < 2; ++$xi) { 233 for ($yi = 0; $yi < 3; ++$yi) { 234 $xPos = $x * 2 + $xi; 235 $yPos = $y * 6 + $yi; 236 237 if (isset($this->_heigth[$xPos][$yPos])) { 238 $color = $this->_mixColor($this->_image[$xPos][$yPos], 239 $this->_heigth[$xPos][$yPos]); 240 if ((($color[0] + $color[1] + $color[2]) / 3) > IMAGE_3D_DRIVER_ASCII_GRAY) { 241 $char |= pow(2, $yi + ($xi * 3)); 242 } 243 $charColor[0] += $color[0]; 244 $charColor[1] += $color[1]; 245 $charColor[2] += $color[2]; 246 } 247 } 248 } 249 $lastColor = $this->_getAnsiColorCode(array($charColor[0] / 6, $charColor[1] / 6, $charColor[2] / 6), $lastColor); 250 $output .= $lastColor . $this->_charArray[$char]; 251 } 252 $lastColor = ''; 253 $output .= "\n"; 254 } 255 $fp = fopen($file, 'w'); 256 fwrite($fp, $output); 257 fclose($fp); 258 } 259 260 public function getSupportedShading() 261 { 262 return array(Image_3D_Renderer::SHADE_NO, 263 Image_3D_Renderer::SHADE_FLAT); 264 } 265} 266 267?> 268