The version of vichan running on lainchan.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
12 anni fa
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. <?php
  2. /*
  3. * Copyright (c) 2010-2013 Tinyboard Development Group
  4. */
  5. defined('TINYBOARD') or exit;
  6. class Image {
  7. public $src, $format, $image, $size;
  8. public function __construct($src, $format = false, $size = false) {
  9. global $config;
  10. $this->src = $src;
  11. $this->format = $format;
  12. if ($config['thumb_method'] == 'imagick') {
  13. $classname = 'ImageImagick';
  14. } elseif (in_array($config['thumb_method'], array('convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'))) {
  15. $classname = 'ImageConvert';
  16. } else {
  17. $classname = 'Image' . strtoupper($this->format);
  18. if (!class_exists($classname)) {
  19. error(_('Unsupported file format: ') . $this->format);
  20. }
  21. }
  22. $this->image = new $classname($this, $size);
  23. if (!$this->image->valid()) {
  24. $this->delete();
  25. error($config['error']['invalidimg']);
  26. }
  27. $this->size = (object)array('width' => $this->image->_width(), 'height' => $this->image->_height());
  28. if ($this->size->width < 1 || $this->size->height < 1) {
  29. $this->delete();
  30. error($config['error']['invalidimg']);
  31. }
  32. }
  33. public function resize($extension, $max_width, $max_height) {
  34. global $config;
  35. if ($config['thumb_method'] == 'imagick') {
  36. $classname = 'ImageImagick';
  37. } elseif ($config['thumb_method'] == 'convert') {
  38. $classname = 'ImageConvert';
  39. } elseif ($config['thumb_method'] == 'convert+gifsicle') {
  40. $classname = 'ImageConvert';
  41. $gifsicle = true;
  42. } elseif ($config['thumb_method'] == 'gm') {
  43. $classname = 'ImageConvert';
  44. $gm = true;
  45. } elseif ($config['thumb_method'] == 'gm+gifsicle') {
  46. $classname = 'ImageConvert';
  47. $gm = true;
  48. $gifsicle = true;
  49. } else {
  50. $classname = 'Image' . strtoupper($extension);
  51. if (!class_exists($classname)) {
  52. error(_('Unsupported file format: ') . $extension);
  53. }
  54. }
  55. $thumb = new $classname(false);
  56. $thumb->src = $this->src;
  57. $thumb->format = $this->format;
  58. $thumb->original_width = $this->size->width;
  59. $thumb->original_height = $this->size->height;
  60. $x_ratio = $max_width / $this->size->width;
  61. $y_ratio = $max_height / $this->size->height;
  62. if (($this->size->width <= $max_width) && ($this->size->height <= $max_height)) {
  63. $width = $this->size->width;
  64. $height = $this->size->height;
  65. } elseif (($x_ratio * $this->size->height) < $max_height) {
  66. $height = ceil($x_ratio * $this->size->height);
  67. $width = $max_width;
  68. } else {
  69. $width = ceil($y_ratio * $this->size->width);
  70. $height = $max_height;
  71. }
  72. $thumb->_resize($this->image->image, $width, $height);
  73. return $thumb;
  74. }
  75. public function to($dst) {
  76. $this->image->to($dst);
  77. }
  78. public function delete() {
  79. file_unlink($this->src);
  80. }
  81. public function destroy() {
  82. $this->image->_destroy();
  83. }
  84. }
  85. class ImageGD {
  86. public function GD_create() {
  87. $this->image = imagecreatetruecolor($this->width, $this->height);
  88. }
  89. public function GD_copyresampled() {
  90. imagecopyresampled($this->image, $this->original, 0, 0, 0, 0, $this->width, $this->height, $this->original_width, $this->original_height);
  91. }
  92. public function GD_resize() {
  93. $this->GD_create();
  94. $this->GD_copyresampled();
  95. }
  96. }
  97. class ImageBase extends ImageGD {
  98. public $image, $src, $original, $original_width, $original_height, $width, $height;
  99. public function valid() {
  100. return (bool)$this->image;
  101. }
  102. public function __construct($img, $size = false) {
  103. if (method_exists($this, 'init'))
  104. $this->init();
  105. if ($size && $size[0] > 0 && $size[1] > 0) {
  106. $this->width = $size[0];
  107. $this->height = $size[1];
  108. }
  109. if ($img !== false) {
  110. $this->src = $img->src;
  111. $this->from();
  112. }
  113. }
  114. public function _width() {
  115. if (method_exists($this, 'width'))
  116. return $this->width();
  117. // use default GD functions
  118. return imagesx($this->image);
  119. }
  120. public function _height() {
  121. if (method_exists($this, 'height'))
  122. return $this->height();
  123. // use default GD functions
  124. return imagesy($this->image);
  125. }
  126. public function _destroy() {
  127. if (method_exists($this, 'destroy'))
  128. return $this->destroy();
  129. // use default GD functions
  130. return imagedestroy($this->image);
  131. }
  132. public function _resize($original, $width, $height) {
  133. $this->original = &$original;
  134. $this->width = $width;
  135. $this->height = $height;
  136. if (method_exists($this, 'resize'))
  137. $this->resize();
  138. else
  139. // use default GD functions
  140. $this->GD_resize();
  141. }
  142. }
  143. class ImageImagick extends ImageBase {
  144. public function init() {
  145. $this->image = new Imagick();
  146. $this->image->setBackgroundColor(new ImagickPixel('transparent'));
  147. }
  148. public function from() {
  149. try {
  150. $this->image->readImage($this->src);
  151. } catch(ImagickException $e) {
  152. // invalid image
  153. $this->image = false;
  154. }
  155. }
  156. public function to($src) {
  157. global $config;
  158. if ($config['strip_exif']) {
  159. $this->image->stripImage();
  160. }
  161. if (preg_match('/\.gif$/i', $src))
  162. $this->image->writeImages($src, true);
  163. else
  164. $this->image->writeImage($src);
  165. }
  166. public function width() {
  167. return $this->image->getImageWidth();
  168. }
  169. public function height() {
  170. return $this->image->getImageHeight();
  171. }
  172. public function destroy() {
  173. return $this->image->destroy();
  174. }
  175. public function resize() {
  176. global $config;
  177. if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '')) {
  178. $this->image = new Imagick();
  179. $this->image->setFormat('gif');
  180. $keep_frames = array();
  181. for ($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames']))
  182. $keep_frames[] = $i;
  183. $i = 0;
  184. $delay = 0;
  185. foreach ($this->original as $frame) {
  186. $delay += $frame->getImageDelay();
  187. if (in_array($i, $keep_frames)) {
  188. // $frame->scaleImage($this->width, $this->height, false);
  189. $frame->sampleImage($this->width, $this->height);
  190. $frame->setImagePage($this->width, $this->height, 0, 0);
  191. $frame->setImageDelay($delay);
  192. $delay = 0;
  193. $this->image->addImage($frame->getImage());
  194. }
  195. $i++;
  196. }
  197. } else {
  198. $this->image = clone $this->original;
  199. $this->image->scaleImage($this->width, $this->height, false);
  200. }
  201. }
  202. }
  203. class ImageConvert extends ImageBase {
  204. public $width, $height, $temp, $gm = false, $gifsicle = false;
  205. public function init() {
  206. global $config;
  207. if ($config['thumb_method'] == 'gm' || $config['thumb_method'] == 'gm+gifsicle')
  208. $this->gm = true;
  209. if ($config['thumb_method'] == 'convert+gifsicle' || $config['thumb_method'] == 'gm+gifsicle')
  210. $this->gifsicle = true;
  211. $this->temp = false;
  212. }
  213. public function get_size($src, $try_gd_first = true) {
  214. if ($try_gd_first) {
  215. if ($size = @getimagesize($src))
  216. return $size;
  217. }
  218. $size = shell_exec_error(($this->gm ? 'gm ' : '') . 'identify -format "%w %h" ' . escapeshellarg($src . '[0]'));
  219. if (preg_match('/^(\d+) (\d+)$/', $size, $m))
  220. return array($m[1], $m[2]);
  221. return false;
  222. }
  223. public function from() {
  224. if ($this->width > 0 && $this->height > 0) {
  225. $this->image = true;
  226. return;
  227. }
  228. $size = $this->get_size($this->src, false);
  229. if ($size) {
  230. $this->width = $size[0];
  231. $this->height = $size[1];
  232. $this->image = true;
  233. } else {
  234. // mark as invalid
  235. $this->image = false;
  236. }
  237. }
  238. public function to($src) {
  239. global $config;
  240. if (!$this->temp) {
  241. if ($config['strip_exif']) {
  242. if($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' .
  243. escapeshellarg($this->src) . ' -auto-orient -strip ' . escapeshellarg($src))) {
  244. $this->destroy();
  245. error(_('Failed to redraw image!'), null, $error);
  246. }
  247. } else {
  248. if($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' .
  249. escapeshellarg($this->src) . ' -auto-orient ' . escapeshellarg($src))) {
  250. $this->destroy();
  251. error(_('Failed to redraw image!'), null, $error);
  252. }
  253. }
  254. } else {
  255. rename($this->temp, $src);
  256. chmod($src, 0664);
  257. }
  258. }
  259. public function width() {
  260. return $this->width;
  261. }
  262. public function height() {
  263. return $this->height;
  264. }
  265. public function destroy() {
  266. @unlink($this->temp);
  267. $this->temp = false;
  268. }
  269. public function resize() {
  270. global $config;
  271. if ($this->temp) {
  272. // remove old
  273. $this->destroy();
  274. }
  275. $this->temp = tempnam($config['tmp'], 'convert');
  276. $config['thumb_keep_animation_frames'] = (int)$config['thumb_keep_animation_frames'];
  277. if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) {
  278. if ($this->gifsicle) {
  279. if (($error = shell_exec("gifsicle -w --unoptimize -O2 --resize {$this->width}x{$this->height} < " .
  280. escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" -o " .
  281. escapeshellarg($this->temp))) || !file_exists($this->temp)) {
  282. $this->destroy();
  283. error(_('Failed to resize image!'), null, $error);
  284. }
  285. } else {
  286. if ($config['convert_manual_orient'] && ($this->format == 'jpg' || $this->format == 'jpeg'))
  287. $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']);
  288. elseif ($config['convert_manual_orient'])
  289. $convert_args = str_replace('-auto-orient', '', $config['convert_args']);
  290. else
  291. $convert_args = &$config['convert_args'];
  292. if (($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' .
  293. sprintf($convert_args,
  294. $this->width,
  295. $this->height,
  296. escapeshellarg($this->src),
  297. $this->width,
  298. $this->height,
  299. escapeshellarg($this->temp)))) || !file_exists($this->temp)) {
  300. $this->destroy();
  301. error(_('Failed to resize image!'), null, $error);
  302. }
  303. if ($size = $this->get_size($this->temp)) {
  304. $this->width = $size[0];
  305. $this->height = $size[1];
  306. }
  307. }
  308. } else {
  309. if ($config['convert_manual_orient'] && ($this->format == 'jpg' || $this->format == 'jpeg'))
  310. $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']);
  311. elseif ($config['convert_manual_orient'])
  312. $convert_args = str_replace('-auto-orient', '', $config['convert_args']);
  313. else
  314. $convert_args = &$config['convert_args'];
  315. if (($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' .
  316. sprintf($convert_args,
  317. $this->width,
  318. $this->height,
  319. escapeshellarg($this->src . '[0]'),
  320. $this->width,
  321. $this->height,
  322. escapeshellarg($this->temp)))) || !file_exists($this->temp)) {
  323. if (strpos($error, "known incorrect sRGB profile") === false &&
  324. strpos($error, "iCCP: Not recognizing known sRGB profile that has been edited") === false) {
  325. $this->destroy();
  326. error(_('Failed to resize image!')." "._('Details: ').nl2br(htmlspecialchars($error)), null, array('convert_error' => $error));
  327. }
  328. if (!file_exists($this->temp)) {
  329. $this->destroy();
  330. error(_('Failed to resize image!'), null, $error);
  331. }
  332. }
  333. if ($size = $this->get_size($this->temp)) {
  334. $this->width = $size[0];
  335. $this->height = $size[1];
  336. }
  337. }
  338. }
  339. // For when -auto-orient doesn't exist (older versions)
  340. static public function jpeg_exif_orientation($src, $exif = false) {
  341. if (!$exif) {
  342. $exif = @exif_read_data($src);
  343. if (!isset($exif['Orientation']))
  344. return false;
  345. }
  346. switch($exif['Orientation']) {
  347. case 1:
  348. // Normal
  349. return false;
  350. case 2:
  351. // 888888
  352. // 88
  353. // 8888
  354. // 88
  355. // 88
  356. return '-flop';
  357. case 3:
  358. // 88
  359. // 88
  360. // 8888
  361. // 88
  362. // 888888
  363. return '-flip -flop';
  364. case 4:
  365. // 88
  366. // 88
  367. // 8888
  368. // 88
  369. // 888888
  370. return '-flip';
  371. case 5:
  372. // 8888888888
  373. // 88 88
  374. // 88
  375. return '-rotate 90 -flop';
  376. case 6:
  377. // 88
  378. // 88 88
  379. // 8888888888
  380. return '-rotate 90';
  381. case 7:
  382. // 88
  383. // 88 88
  384. // 8888888888
  385. return '-rotate "-90" -flop';
  386. case 8:
  387. // 8888888888
  388. // 88 88
  389. // 88
  390. return '-rotate "-90"';
  391. }
  392. }
  393. }
  394. class ImagePNG extends ImageBase {
  395. public function from() {
  396. $this->image = @imagecreatefrompng($this->src);
  397. }
  398. public function to($src) {
  399. global $config;
  400. imagepng($this->image, $src);
  401. }
  402. public function resize() {
  403. $this->GD_create();
  404. imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0));
  405. imagesavealpha($this->image, true);
  406. imagealphablending($this->image, false);
  407. $this->GD_copyresampled();
  408. }
  409. }
  410. class ImageGIF extends ImageBase {
  411. public function from() {
  412. $this->image = @imagecreatefromgif($this->src);
  413. }
  414. public function to($src) {
  415. imagegif ($this->image, $src);
  416. }
  417. public function resize() {
  418. $this->GD_create();
  419. imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0));
  420. imagesavealpha($this->image, true);
  421. $this->GD_copyresampled();
  422. }
  423. }
  424. class ImageJPG extends ImageBase {
  425. public function from() {
  426. $this->image = @imagecreatefromjpeg($this->src);
  427. }
  428. public function to($src) {
  429. imagejpeg($this->image, $src);
  430. }
  431. }
  432. class ImageJPEG extends ImageJPG {
  433. }
  434. class ImageBMP extends ImageBase {
  435. public function from() {
  436. $this->image = @imagecreatefrombmp($this->src);
  437. }
  438. public function to($src) {
  439. imagebmp($this->image, $src);
  440. }
  441. }
  442. /*********************************************/
  443. /* Fonction: imagecreatefrombmp */
  444. /* Author: DHKold */
  445. /* Contact: admin@dhkold.com */
  446. /* Date: The 15th of June 2005 */
  447. /* Version: 2.0B */
  448. /*********************************************/
  449. function imagecreatefrombmp($filename) {
  450. if (! $f1 = fopen($filename,"rb")) return FALSE;
  451. $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
  452. if ($FILE['file_type'] != 19778) return FALSE;
  453. $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
  454. '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
  455. '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
  456. $BMP['colors'] = pow(2,$BMP['bits_per_pixel']);
  457. if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
  458. $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
  459. $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
  460. $BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
  461. $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
  462. $BMP['decal'] = 4-(4*$BMP['decal']);
  463. if ($BMP['decal'] == 4) $BMP['decal'] = 0;
  464. $PALETTE = array();
  465. if ($BMP['colors'] < 16777216)
  466. {
  467. $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
  468. }
  469. $IMG = fread($f1,$BMP['size_bitmap']);
  470. $VIDE = chr(0);
  471. $res = imagecreatetruecolor($BMP['width'],$BMP['height']);
  472. $P = 0;
  473. $Y = $BMP['height']-1;
  474. while ($Y >= 0)
  475. {
  476. $X=0;
  477. while ($X < $BMP['width'])
  478. {
  479. if ($BMP['bits_per_pixel'] == 24)
  480. $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
  481. elseif ($BMP['bits_per_pixel'] == 16)
  482. {
  483. $COLOR = unpack("n",substr($IMG,$P,2));
  484. $COLOR[1] = $PALETTE[$COLOR[1]+1];
  485. }
  486. elseif ($BMP['bits_per_pixel'] == 8)
  487. {
  488. $COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
  489. $COLOR[1] = $PALETTE[$COLOR[1]+1];
  490. }
  491. elseif ($BMP['bits_per_pixel'] == 4)
  492. {
  493. $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
  494. if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
  495. $COLOR[1] = $PALETTE[$COLOR[1]+1];
  496. }
  497. elseif ($BMP['bits_per_pixel'] == 1)
  498. {
  499. $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
  500. if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7;
  501. elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
  502. elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
  503. elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
  504. elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
  505. elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
  506. elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
  507. elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
  508. $COLOR[1] = $PALETTE[$COLOR[1]+1];
  509. }
  510. else
  511. return FALSE;
  512. imagesetpixel($res,$X,$Y,$COLOR[1]);
  513. $X++;
  514. $P += $BMP['bytes_per_pixel'];
  515. }
  516. $Y--;
  517. $P+=$BMP['decal'];
  518. }
  519. fclose($f1);
  520. return $res;
  521. }
  522. function imagebmp(&$img, $filename='') {
  523. $widthOrig = imagesx($img);
  524. $widthFloor = ((floor($widthOrig/16))*16);
  525. $widthCeil = ((ceil($widthOrig/16))*16);
  526. $height = imagesy($img);
  527. $size = ($widthCeil*$height*3)+54;
  528. // Bitmap File Header
  529. $result = 'BM'; // header (2b)
  530. $result .= int_to_dword($size); // size of file (4b)
  531. $result .= int_to_dword(0); // reserved (4b)
  532. $result .= int_to_dword(54); // byte location in the file which is first byte of IMAGE (4b)
  533. // Bitmap Info Header
  534. $result .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
  535. $result .= int_to_dword($widthCeil); // width of bitmap (4b)
  536. $result .= int_to_dword($height); // height of bitmap (4b)
  537. $result .= int_to_word(1); // biPlanes = 1 (2b)
  538. $result .= int_to_word(24); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b
  539. $result .= int_to_dword(0); // RLE COMPRESSION (4b)
  540. $result .= int_to_dword(0); // width x height (4b)
  541. $result .= int_to_dword(0); // biXPelsPerMeter (4b)
  542. $result .= int_to_dword(0); // biYPelsPerMeter (4b)
  543. $result .= int_to_dword(0); // Number of palettes used (4b)
  544. $result .= int_to_dword(0); // Number of important colour (4b)
  545. // is faster than chr()
  546. $arrChr = array();
  547. for ($i=0; $i<256; $i++){
  548. $arrChr[$i] = chr($i);
  549. }
  550. // creates image data
  551. $bgfillcolor = array('red'=>0, 'green'=>0, 'blue'=>0);
  552. // bottom to top - left to right - attention blue green red !!!
  553. $y=$height-1;
  554. for ($y2=0; $y2<$height; $y2++) {
  555. for ($x=0; $x<$widthFloor; ) {
  556. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  557. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  558. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  559. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  560. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  561. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  562. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  563. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  564. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  565. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  566. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  567. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  568. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  569. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  570. $rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y));
  571. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  572. }
  573. for ($x=$widthFloor; $x<$widthCeil; $x++) {
  574. $rgb = ($x<$widthOrig) ? imagecolorsforindex($img, imagecolorat($img, $x, $y)) : $bgfillcolor;
  575. $result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']];
  576. }
  577. $y--;
  578. }
  579. // see imagegif
  580. if ($filename == '') {
  581. echo $result;
  582. } else {
  583. $file = fopen($filename, 'wb');
  584. fwrite($file, $result);
  585. fclose($file);
  586. }
  587. }
  588. // imagebmp helpers
  589. function int_to_dword($n) {
  590. return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
  591. }
  592. function int_to_word($n) {
  593. return chr($n & 255).chr(($n >> 8) & 255);
  594. }