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.

img2txt.php 12 KiB

16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
16 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. <?php
  2. /*
  3. * img2txt image to text converter
  4. * Copyright (c) 2008 Benjamin C. Wiley Sittler <bsittler@gmail.com>
  5. *
  6. * This file is a Php port of "src/img2txt.c"
  7. * which is:
  8. * Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
  9. * 2007 Jean-Yves Lamoureux <jylam@lnxscene.org>
  10. * All Rights Reserved
  11. *
  12. * $Id$
  13. *
  14. * This program is free software. It comes without any warranty, to
  15. * the extent permitted by applicable law. You can redistribute it
  16. * and/or modify it under the terms of the Do What The Fuck You Want
  17. * To Public License, Version 2, as published by Sam Hocevar. See
  18. * http://sam.zoy.org/wtfpl/COPYING for more details.
  19. */
  20. $img2txt_php = isset($_SERVER['SCRIPT_NAME'])
  21. ?
  22. $_SERVER['SCRIPT_NAME']
  23. :
  24. 'img2txt.php';
  25. $argv = array(basename($img2txt_php));
  26. $args = '';
  27. if(isset($_REQUEST['args']))
  28. {
  29. $args = $_REQUEST['args'];
  30. }
  31. $args=trim($args);
  32. if(strlen($args))
  33. {
  34. foreach(explode(' ', $args) as $arg)
  35. {
  36. $argv[] = $arg;
  37. }
  38. }
  39. $argc = count($argv);
  40. $stderr = '';
  41. $stdout = '';
  42. class MygetoptException extends Exception
  43. {
  44. }
  45. $myoptind = 0;
  46. function mygetopt($shortopts, $longopts)
  47. {
  48. global $argc, $argv, $myoptind;
  49. if($myoptind < 0)
  50. {
  51. $myoptind = 0;
  52. }
  53. if(($myoptind + 1) >= $argc)
  54. {
  55. return NULL;
  56. }
  57. $myoptind ++;
  58. $nextarg = $argv[$myoptind];
  59. $ret = NULL;
  60. if((substr($nextarg, 0, 1) != '-')
  61. ||
  62. ($nextarg == '-'))
  63. {
  64. $myoptind = $argc - 1;
  65. }
  66. else
  67. {
  68. $skipopt = $myoptind;
  69. $skipopts = 1;
  70. if($nextarg == '--')
  71. {
  72. $myoptind = $argc - 1;
  73. }
  74. else
  75. {
  76. $opt = NULL;
  77. $arg = NULL;
  78. foreach($longopts as $longopt)
  79. {
  80. $optional = false;
  81. $hasarg = false;
  82. if(($longopt != '::') && substr($longopt, -2) == '::')
  83. {
  84. $optional = true;
  85. $hasarg = true;
  86. $longopt = substr($longopt, 0, -2);
  87. }
  88. else if(($longopt != ':') && substr($longopt, -1) == ':')
  89. {
  90. $optional = false;
  91. $hasarg = true;
  92. $longopt = substr($longopt, 0, -1);
  93. }
  94. if($nextarg == ('--' . $longopt))
  95. {
  96. $opt = '--' . $longopt;
  97. if($hasarg && ! $optional)
  98. {
  99. if(($myoptind + 1) < $argc)
  100. {
  101. $myoptind ++;
  102. $skipopts ++;
  103. $arg = $argv[$myoptind];
  104. }
  105. else
  106. {
  107. throw new MygetoptException("option \"$opt\" requires an argument");
  108. }
  109. }
  110. break;
  111. }
  112. else if(substr($nextarg, 0, strlen('--' . $longopt . '='))
  113. ==
  114. ('--' . $longopt . '='))
  115. {
  116. $opt = '--' . $longopt;
  117. $arg = substr($nextarg, strlen($opt . '='));
  118. if(! $hasarg)
  119. {
  120. throw new MygetoptException("option \"$opt\" does not allow an argument");
  121. }
  122. break;
  123. }
  124. }
  125. if($opt === NULL)
  126. {
  127. for($i = 0; $i < strlen($shortopts); $i ++)
  128. {
  129. $optional = false;
  130. $hasarg = false;
  131. $shortopt = substr($shortopts, $i, 1);
  132. if(substr($shortopts, $i + 1, 2) == '::')
  133. {
  134. $optional = true;
  135. $hasarg = true;
  136. $i += 2;
  137. }
  138. else if(substr($shortopts, $i + 1, 1) == ':')
  139. {
  140. $hasarg = true;
  141. }
  142. if($nextarg
  143. ==
  144. ('-' . $shortopt))
  145. {
  146. $opt = '-' . $shortopt;
  147. if($hasarg && ! $optional)
  148. {
  149. if(($myoptind + 1) < $argc)
  150. {
  151. $myoptind ++;
  152. $skipopts ++;
  153. $arg = $argv[$myoptind];
  154. }
  155. else
  156. {
  157. throw new MygetoptException("option \"$opt\" requires an argument");
  158. }
  159. }
  160. break;
  161. }
  162. else if(substr($nextarg, 0, strlen('-' . $shortopt))
  163. ==
  164. ('-' . $shortopt))
  165. {
  166. $opt = '-' . $shortopt;
  167. if($hasarg)
  168. {
  169. $arg = substr($nextarg, strlen($opt));
  170. }
  171. else
  172. {
  173. $argv[$myoptind] = '-' . substr($nextarg, strlen($opt));
  174. $myoptind --;
  175. $skipopts = 0;
  176. }
  177. }
  178. }
  179. }
  180. if($opt === NULL)
  181. {
  182. if(substr($nextarg, 0, strlen('--')) == '--')
  183. {
  184. $longopt = substr($nextarg, strlen('--'));
  185. if(strpos($longopt, '=') !== false)
  186. {
  187. $longopt = substr($longopt, 0, strpos($longopt, '='));
  188. }
  189. throw new MygetoptException("option \"--$longopt\" is not recognized");
  190. }
  191. $shortopt = substr($nextarg, strlen('-'), 1);
  192. throw new MygetoptException("option \"-$shortopt\" is not recognized");
  193. }
  194. $ret = array($opt, $arg);
  195. }
  196. if ($skipopts > 0)
  197. {
  198. for($i = 0; $i < $argc; $i ++)
  199. {
  200. if(($i < $skipopt) || ($i >= ($skipopt + $skipopts)))
  201. {
  202. $new_argv[] = $argv[$i];
  203. }
  204. }
  205. if($myoptind >= $skipopt)
  206. {
  207. $myoptind -= $skipopts;
  208. }
  209. $argv = $new_argv;
  210. $argc = count($argv);
  211. }
  212. }
  213. return $ret;
  214. }
  215. function usage($argc, $argv)
  216. {
  217. global $stderr;
  218. $stderr .= sprintf("Usage: %s [OPTIONS]... <IMAGE>\n", $argv[0]);
  219. $stderr .= sprintf("Convert IMAGE to any text based available format.\n");
  220. $stderr .= sprintf("Example : %s -w 80 -f ansi ./caca.png\n\n", $argv[0]);
  221. $stderr .= sprintf("Options:\n");
  222. $stderr .= sprintf(" -h, --help\t\t\tThis help\n");
  223. $stderr .= sprintf(" -v, --version\t\t\tVersion of the program\n");
  224. $stderr .= sprintf(" -W, --width=WIDTH\t\tWidth of resulting image\n");
  225. $stderr .= sprintf(" -H, --height=HEIGHT\t\tHeight of resulting image\n");
  226. $stderr .= sprintf(" -x, --font-width=WIDTH\t\tWidth of output font\n");
  227. $stderr .= sprintf(" -y, --font-height=HEIGHT\t\tHeight of output font\n");
  228. $stderr .= sprintf(" -b, --brightness=BRIGHTNESS\tBrightness of resulting image\n");
  229. $stderr .= sprintf(" -c, --contrast=CONTRAST\tContrast of resulting image\n");
  230. $stderr .= sprintf(" -g, --gamma=GAMMA\t\tGamma of resulting image\n");
  231. $stderr .= sprintf(" -d, --dither=DITHER\t\tDithering algorithm to use :\n");
  232. $list = caca_get_dither_algorithm_list(caca_create_dither(imagecreate(1, 1)));
  233. foreach($list as $type => $name)
  234. {
  235. $stderr .= sprintf("\t\t\t%s: %s\n", $type, $name);
  236. }
  237. $stderr .= sprintf(" -f, --format=FORMAT\t\tFormat of the resulting image :\n");
  238. $list = caca_get_export_list();
  239. foreach($list as $type => $name)
  240. {
  241. $stderr .= sprintf("\t\t\t%s: %s\n", $type, $name);
  242. }
  243. }
  244. function version()
  245. {
  246. global $stdout;
  247. $stdout .= sprintf(
  248. "img2txt Copyright 2006-2007 Sam Hocevar and Jean-Yves Lamoureux\n" .
  249. "Internet: <sam@zoy.org> <jylam@lnxscene.org> Version: %s\n" .
  250. "\n" .
  251. "img2txt, along with its documentation, may be freely copied and distributed.\n" .
  252. "\n" .
  253. "The latest version of img2txt is available from the web site,\n" .
  254. " http://caca.zoy.org/wiki/libcaca in the libcaca package.\n" .
  255. "\n",
  256. caca_get_version());
  257. }
  258. function main()
  259. {
  260. global $argc, $argv;
  261. global $stderr;
  262. $cols = 0;
  263. $lines = 0;
  264. $font_width = 6;
  265. $font_height = 10;
  266. $format = NULL;
  267. $dither = NULL;
  268. $gamma = $brightness = $contrast = -1.0;
  269. $long_options = array(
  270. "width:" => 'W',
  271. "height:" => 'H',
  272. "font-width:" => 'x',
  273. "font-height:" => 'y',
  274. "format:" => 'f',
  275. "dither:" => 'd',
  276. "gamma:" => 'g',
  277. "brightness:" => 'b',
  278. "contrast:" => 'c',
  279. "help" => 'h',
  280. "version" => 'v'
  281. );
  282. try {
  283. while($opt_and_arg = mygetopt("W:H:f:d:g:b:c:hvx:y:", array_keys($long_options)))
  284. {
  285. $opt = $opt_and_arg[0];
  286. $arg = $opt_and_arg[1];
  287. if((substr($opt, 0, 2) == '--')
  288. &&
  289. array_key_exists(substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : ''), $long_options))
  290. {
  291. $opt = '-' . $long_options[substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : '')];
  292. }
  293. switch($opt)
  294. {
  295. case '-W': /* --width */
  296. $cols = intval($arg);
  297. break;
  298. case '-H': /* --height */
  299. $lines = intval($arg);
  300. break;
  301. case '-x': /* --width */
  302. $font_width = intval($arg);
  303. break;
  304. case '-y': /* --height */
  305. $font_height = intval($arg);
  306. break;
  307. case '-f': /* --format */
  308. $format = $arg;
  309. break;
  310. case '-d': /* --dither */
  311. $dither = $arg;
  312. break;
  313. case '-g': /* --gamma */
  314. $gamma = floatval($arg);
  315. break;
  316. case '-b': /* --brightness */
  317. $brightness = floatval($arg);
  318. break;
  319. case '-c': /* --contrast */
  320. $contrast = floatval($arg);
  321. break;
  322. case '-h': /* --help */
  323. usage($argc, $argv);
  324. return 0;
  325. case '-v': /* --version */
  326. version();
  327. return 0;
  328. default:
  329. return 1;
  330. }
  331. }
  332. }
  333. catch (MygetoptException $e)
  334. {
  335. $stderr .= $argv[0] . ": " . $e->getMessage() . "\n";
  336. usage($argc, $argv);
  337. return 2;
  338. }
  339. if($argc > 1)
  340. {
  341. $stderr .= sprintf("%s: too many arguments\n", $argv[0]);
  342. usage($argc, $argv);
  343. return 1;
  344. }
  345. $file = isset($_FILES['file']) ? $_FILES['file']['tmp_name'] : NULL;
  346. $filename = isset($_FILES['file']) ? $_FILES['file']['name'] : NULL;
  347. if(! $file)
  348. {
  349. $stderr .= sprintf("%s: no image was provided\n", $argv[0]);
  350. usage($argc, $argv);
  351. return 1;
  352. }
  353. $cv = caca_create_canvas(0, 0);
  354. if(!$cv)
  355. {
  356. $stderr .= sprintf("%s: unable to initialise libcaca\n", $argv[0]);
  357. return 1;
  358. }
  359. $i_str = $file ? file_get_contents($file) : NULL;
  360. $i = $i_str ? imagecreatefromstring($i_str) : NULL;
  361. if(!$i)
  362. {
  363. $stderr .= sprintf("%s: unable to load %s\n", $argv[0], $filename);
  364. return 1;
  365. }
  366. /* Assume a 6×10 font */
  367. if(!$cols && !$lines)
  368. {
  369. $cols = 60;
  370. $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
  371. }
  372. else if($cols && !$lines)
  373. {
  374. $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
  375. }
  376. else if(!$cols && $lines)
  377. {
  378. $cols = $lines * imagesx($i) * $font_height / imagesy($i) / $font_width;
  379. }
  380. caca_set_canvas_size($cv, $cols, $lines);
  381. caca_set_color_ansi($cv, CACA_DEFAULT, CACA_TRANSPARENT);
  382. caca_clear_canvas($cv);
  383. $i_dither = caca_create_dither($i);
  384. if(! caca_set_dither_algorithm($i_dither, $dither?$dither:"fstein"))
  385. {
  386. $stderr .= sprintf("%s: Can't dither image with algorithm '%s'\n", $argv[0], $dither?$dither:"fstein");
  387. return -1;
  388. }
  389. if($brightness!=-1) caca_set_dither_brightness ($i_dither, $brightness);
  390. if($contrast!=-1) caca_set_dither_contrast ($i_dither, $contrast);
  391. if($gamma!=-1) caca_set_dither_gamma ($i_dither, $gamma);
  392. caca_dither_bitmap($cv, 0, 0, $cols, $lines, $i_dither, $i);
  393. $format = $format ? $format : 'html';
  394. $export = caca_export_string($cv, $format);
  395. if(!$export)
  396. {
  397. $stderr .= sprintf("%s: Can't export to format '%s'\n", $argv[0], $format);
  398. return -1;
  399. }
  400. else
  401. {
  402. $content_type_map = array(
  403. 'ansi' => 'text/plain; charset=CP437',
  404. 'utf8' => 'text/plain; charset=UTF-8',
  405. 'utf8cr' => 'text/plain; charset=UTF-8',
  406. 'html' => 'text/html; charset=UTF-8',
  407. 'html3' => 'text/html; charset=UTF-8',
  408. 'bbfr' => 'text/plain; charset=UTF-8',
  409. 'irc' => 'text/plain; charset=UTF-8',
  410. 'ps' => 'application/postscript',
  411. 'svg' => 'image/svg+xml',
  412. 'tga' => 'image/x-targa'
  413. );
  414. $download_extension_map = array(
  415. 'caca' => 'caca',
  416. 'ansi' => 'txt',
  417. 'utf8' => 'txt',
  418. 'utf8cr' => 'txt',
  419. 'irc' => 'txt',
  420. 'tga' => 'tga'
  421. );
  422. $inline_extension_map = array(
  423. 'bbfr' => 'txt',
  424. 'ps' => 'ps',
  425. 'svg' => 'svg'
  426. );
  427. if (! array_key_exists($format, $content_type_map))
  428. $content_type = 'application/octet-stream';
  429. else
  430. $content_type = $content_type_map[$format];
  431. header('Content-Type: ' . $content_type);
  432. if (array_key_exists($format, $download_extension_map))
  433. header('Content-Disposition: attachment; filename=export.' . $download_extension_map[$format]);
  434. else if (array_key_exists($format, $inline_extension_map))
  435. header('Content-Disposition: inline; filename=export.' . $inline_extension_map[$format]);
  436. echo $export;
  437. }
  438. return 0;
  439. }
  440. if(main() || strlen($stdout) || strlen($stderr))
  441. {
  442. header('Content-Type: text/html; charset=UTF-8');
  443. ?>
  444. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  445. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  446. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  447. <head>
  448. <title>image to text converter</title>
  449. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  450. </head>
  451. <body>
  452. <form id="img2txtform" name="img2txtform" action="#" enctype="multipart/form-data" method="post">
  453. <label for="file">Image:</label>
  454. <input id="file" name="file" type="file" />
  455. <br />
  456. <label for="args">Options:</label>
  457. <input id="args" name="args" type="text" value="<?= htmlspecialchars($args) ?>" size="80" />
  458. <br />
  459. <input type="submit" />
  460. </form>
  461. <?php
  462. ;
  463. if(strlen($stderr))
  464. {
  465. ?><pre xml:space="preserve"><em><?= htmlspecialchars($stderr) ?></em></pre><?php
  466. ;
  467. }
  468. if(strlen($stdout))
  469. {
  470. ?><pre xml:space="preserve"><?= htmlspecialchars($stdout) ?></pre><?php
  471. ;
  472. }
  473. ?>
  474. </body>
  475. </html>
  476. <?php
  477. ;
  478. }
  479. ?>