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 13 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #!/usr/bin/php5
  2. <?php
  3. /*
  4. * img2txt image to text converter
  5. * Copyright (c) 2008 Benjamin C. Wiley Sittler <bsittler@gmail.com>
  6. *
  7. * This file is a Php port of "src/img2txt.c"
  8. * which is:
  9. * Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
  10. * 2007 Jean-Yves Lamoureux <jylam@lnxscene.org>
  11. * All Rights Reserved
  12. *
  13. * This program is free software. It comes without any warranty, to
  14. * the extent permitted by applicable law. You can redistribute it
  15. * and/or modify it under the terms of the Do What The Fuck You Want
  16. * To Public License, Version 2, as published by Sam Hocevar. See
  17. * http://sam.zoy.org/wtfpl/COPYING for more details.
  18. */
  19. if (php_sapi_name() != "cli") {
  20. die("You have to run this program with php-cli!\n");
  21. }
  22. class MygetoptException extends Exception
  23. {
  24. }
  25. $myoptind = 0;
  26. function mygetopt($shortopts, $longopts)
  27. {
  28. global $argc, $argv, $myoptind;
  29. if($myoptind < 0)
  30. {
  31. $myoptind = 0;
  32. }
  33. if(($myoptind + 1) >= $argc)
  34. {
  35. return NULL;
  36. }
  37. $myoptind ++;
  38. $nextarg = $argv[$myoptind];
  39. $ret = NULL;
  40. if((substr($nextarg, 0, 1) != '-')
  41. ||
  42. ($nextarg == '-'))
  43. {
  44. $myoptind = $argc - 1;
  45. }
  46. else
  47. {
  48. $skipopt = $myoptind;
  49. $skipopts = 1;
  50. if($nextarg == '--')
  51. {
  52. $myoptind = $argc - 1;
  53. }
  54. else
  55. {
  56. $opt = NULL;
  57. $arg = NULL;
  58. foreach($longopts as $longopt)
  59. {
  60. $optional = false;
  61. $hasarg = false;
  62. if(($longopt != '::') && substr($longopt, -2) == '::')
  63. {
  64. $optional = true;
  65. $hasarg = true;
  66. $longopt = substr($longopt, 0, -2);
  67. }
  68. else if(($longopt != ':') && substr($longopt, -1) == ':')
  69. {
  70. $optional = false;
  71. $hasarg = true;
  72. $longopt = substr($longopt, 0, -1);
  73. }
  74. if($nextarg == ('--' . $longopt))
  75. {
  76. $opt = '--' . $longopt;
  77. if($hasarg && ! $optional)
  78. {
  79. if(($myoptind + 1) < $argc)
  80. {
  81. $myoptind ++;
  82. $skipopts ++;
  83. $arg = $argv[$myoptind];
  84. }
  85. else
  86. {
  87. throw new MygetoptException("option \"$opt\" requires an argument");
  88. }
  89. }
  90. break;
  91. }
  92. else if(substr($nextarg, 0, strlen('--' . $longopt . '='))
  93. ==
  94. ('--' . $longopt . '='))
  95. {
  96. $opt = '--' . $longopt;
  97. $arg = substr($nextarg, strlen($opt . '='));
  98. if(! $hasarg)
  99. {
  100. throw new MygetoptException("option \"$opt\" does not allow an argument");
  101. }
  102. break;
  103. }
  104. }
  105. if($opt === NULL)
  106. {
  107. for($i = 0; $i < strlen($shortopts); $i ++)
  108. {
  109. $optional = false;
  110. $hasarg = false;
  111. $shortopt = substr($shortopts, $i, 1);
  112. if(substr($shortopts, $i + 1, 2) == '::')
  113. {
  114. $optional = true;
  115. $hasarg = true;
  116. $i += 2;
  117. }
  118. else if(substr($shortopts, $i + 1, 1) == ':')
  119. {
  120. $hasarg = true;
  121. }
  122. if($nextarg
  123. ==
  124. ('-' . $shortopt))
  125. {
  126. $opt = '-' . $shortopt;
  127. if($hasarg && ! $optional)
  128. {
  129. if(($myoptind + 1) < $argc)
  130. {
  131. $myoptind ++;
  132. $skipopts ++;
  133. $arg = $argv[$myoptind];
  134. }
  135. else
  136. {
  137. throw new MygetoptException("option \"$opt\" requires an argument");
  138. }
  139. }
  140. break;
  141. }
  142. else if(substr($nextarg, 0, strlen('-' . $shortopt))
  143. ==
  144. ('-' . $shortopt))
  145. {
  146. $opt = '-' . $shortopt;
  147. if($hasarg)
  148. {
  149. $arg = substr($nextarg, strlen($opt));
  150. }
  151. else
  152. {
  153. $argv[$myoptind] = '-' . substr($nextarg, strlen($opt));
  154. $myoptind --;
  155. $skipopts = 0;
  156. }
  157. }
  158. }
  159. }
  160. if($opt === NULL)
  161. {
  162. if(substr($nextarg, 0, strlen('--')) == '--')
  163. {
  164. $longopt = substr($nextarg, strlen('--'));
  165. if(strpos($longopt, '=') !== false)
  166. {
  167. $longopt = substr($longopt, 0, strpos($longopt, '='));
  168. }
  169. throw new MygetoptException("option \"--$longopt\" is not recognized");
  170. }
  171. $shortopt = substr($nextarg, strlen('-'), 1);
  172. throw new MygetoptException("option \"-$shortopt\" is not recognized");
  173. }
  174. $ret = array($opt, $arg);
  175. }
  176. if ($skipopts > 0)
  177. {
  178. for($i = 0; $i < $argc; $i ++)
  179. {
  180. if(($i < $skipopt) || ($i >= ($skipopt + $skipopts)))
  181. {
  182. $new_argv[] = $argv[$i];
  183. }
  184. }
  185. if($myoptind >= $skipopt)
  186. {
  187. $myoptind -= $skipopts;
  188. }
  189. $argv = $new_argv;
  190. $argc = count($argv);
  191. }
  192. }
  193. return $ret;
  194. }
  195. function usage($argc, $argv)
  196. {
  197. fprintf(STDERR, "Usage: %s [OPTIONS]... <IMAGE>\n", $argv[0]);
  198. fprintf(STDERR, "Convert IMAGE to any text based available format.\n");
  199. fprintf(STDERR, "Example : %s -W 80 -f ansi ./caca.png\n\n", $argv[0]);
  200. fprintf(STDERR, "Options:\n");
  201. fprintf(STDERR, " -h, --help\t\t\tThis help\n");
  202. fprintf(STDERR, " -v, --version\t\t\tVersion of the program\n");
  203. fprintf(STDERR, " -W, --width=WIDTH\t\tWidth of resulting image\n");
  204. fprintf(STDERR, " -H, --height=HEIGHT\t\tHeight of resulting image\n");
  205. fprintf(STDERR, " -x, --font-width=WIDTH\t\tWidth of output font\n");
  206. fprintf(STDERR, " -y, --font-height=HEIGHT\t\tHeight of output font\n");
  207. fprintf(STDERR, " -b, --brightness=BRIGHTNESS\tBrightness of resulting image\n");
  208. fprintf(STDERR, " -c, --contrast=CONTRAST\tContrast of resulting image\n");
  209. fprintf(STDERR, " -g, --gamma=GAMMA\t\tGamma of resulting image\n");
  210. fprintf(STDERR, " -d, --dither=DITHER\t\tDithering algorithm to use :\n");
  211. $list = caca_get_dither_algorithm_list(caca_create_dither(imagecreate(1, 1)));
  212. foreach($list as $type => $name)
  213. {
  214. fprintf(STDERR, "\t\t\t%s: %s\n", $type, $name);
  215. }
  216. fprintf(STDERR, " -f, --format=FORMAT\t\tFormat of the resulting image :\n");
  217. $list = caca_get_export_list();
  218. foreach($list as $type => $name)
  219. {
  220. fprintf(STDERR, "\t\t\t%s: %s\n", $type, $name);
  221. }
  222. }
  223. function version()
  224. {
  225. printf(
  226. "img2txt Copyright 2006-2007 Sam Hocevar and Jean-Yves Lamoureux\n" .
  227. " Copyright 2008 Benjamin C. Wiley Sittler\n" .
  228. "Internet: <sam@hocevar.net> <jylam@lnxscene.org>\n" .
  229. " <bsittler@gmail.com> Version: %s\n" .
  230. "\n" .
  231. "img2txt, along with its documentation, may be freely copied and distributed.\n" .
  232. "\n" .
  233. "The latest version of img2txt is available from the web site,\n" .
  234. " http://caca.zoy.org/wiki/libcaca in the libcaca package.\n" .
  235. "\n",
  236. caca_get_version());
  237. }
  238. function main()
  239. {
  240. global $argc, $argv;
  241. $cols = 0;
  242. $lines = 0;
  243. $font_width = 6;
  244. $font_height = 10;
  245. $format = NULL;
  246. $dither = NULL;
  247. $gamma = $brightness = $contrast = -1.0;
  248. $long_options = array(
  249. "width:" => 'W',
  250. "height:" => 'H',
  251. "font-width:" => 'x',
  252. "font-height:" => 'y',
  253. "format:" => 'f',
  254. "dither:" => 'd',
  255. "gamma:" => 'g',
  256. "brightness:" => 'b',
  257. "contrast:" => 'c',
  258. "help" => 'h',
  259. "version" => 'v'
  260. );
  261. try {
  262. while($opt_and_arg = mygetopt("W:H:f:d:g:b:c:hvx:y:", array_keys($long_options)))
  263. {
  264. $opt = $opt_and_arg[0];
  265. $arg = $opt_and_arg[1];
  266. if((substr($opt, 0, 2) == '--')
  267. &&
  268. array_key_exists(substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : ''), $long_options))
  269. {
  270. $opt = '-' . $long_options[substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : '')];
  271. }
  272. switch($opt)
  273. {
  274. case '-W': /* --width */
  275. $cols = intval($arg);
  276. break;
  277. case '-H': /* --height */
  278. $lines = intval($arg);
  279. break;
  280. case '-x': /* --width */
  281. $font_width = intval($arg);
  282. break;
  283. case '-y': /* --height */
  284. $font_height = intval($arg);
  285. break;
  286. case '-f': /* --format */
  287. $format = $arg;
  288. break;
  289. case '-d': /* --dither */
  290. $dither = $arg;
  291. break;
  292. case '-g': /* --gamma */
  293. $gamma = floatval($arg);
  294. break;
  295. case '-b': /* --brightness */
  296. $brightness = floatval($arg);
  297. break;
  298. case '-c': /* --contrast */
  299. $contrast = floatval($arg);
  300. break;
  301. case '-h': /* --help */
  302. usage($argc, $argv);
  303. return 0;
  304. case '-v': /* --version */
  305. version();
  306. return 0;
  307. default:
  308. return 1;
  309. }
  310. }
  311. }
  312. catch (MygetoptException $e)
  313. {
  314. fprintf(STDERR, "%s", $argv[0] . ": " . $e->getMessage() . "\n");
  315. usage($argc, $argv);
  316. return 2;
  317. }
  318. if($argc != 2)
  319. {
  320. fprintf(STDERR, "%s: wrong argument count\n", $argv[0]);
  321. usage($argc, $argv);
  322. return 1;
  323. }
  324. $cv = caca_create_canvas(0, 0);
  325. if(!$cv)
  326. {
  327. fprintf(STDERR, "%s: unable to initialise libcaca\n", $argv[0]);
  328. return 1;
  329. }
  330. $i_str = file_get_contents($argv[$argc-1]);
  331. $i = $i_str ? imagecreatefromstring($i_str) : NULL;
  332. if(!$i)
  333. {
  334. fprintf(STDERR, "%s: unable to load %s\n", $argv[0], $argv[$argc-1]);
  335. return 1;
  336. }
  337. /* Assume a 6×10 font */
  338. if(!$cols && !$lines)
  339. {
  340. $cols = 60;
  341. $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
  342. }
  343. else if($cols && !$lines)
  344. {
  345. $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
  346. }
  347. else if(!$cols && $lines)
  348. {
  349. $cols = $lines * imagesx($i) * $font_height / imagesy($i) / $font_width;
  350. }
  351. caca_set_canvas_size($cv, $cols, $lines);
  352. caca_set_color_ansi($cv, CACA_DEFAULT, CACA_TRANSPARENT);
  353. caca_clear_canvas($cv);
  354. $i_dither = caca_create_dither($i);
  355. if(! caca_set_dither_algorithm($i_dither, $dither?$dither:"fstein"))
  356. {
  357. fprintf(STDERR, "%s: Can't dither image with algorithm '%s'\n", $argv[0], $dither?$dither:"fstein");
  358. return -1;
  359. }
  360. if($brightness!=-1) caca_set_dither_brightness ($i_dither, $brightness);
  361. if($contrast!=-1) caca_set_dither_contrast ($i_dither, $contrast);
  362. if($gamma!=-1) caca_set_dither_gamma ($i_dither, $gamma);
  363. caca_dither_bitmap($cv, 0, 0, $cols, $lines, $i_dither, $i);
  364. $export = caca_export_string($cv, $format?$format:"ansi");
  365. if(!$export)
  366. {
  367. fprintf(STDERR, "%s: Can't export to format '%s'\n", $argv[0], $format?$format:"ansi");
  368. return -1;
  369. }
  370. else
  371. {
  372. echo $export;
  373. }
  374. return 0;
  375. }
  376. exit(main());
  377. ?>