source: libcaca/trunk/caca-php/examples/www/img2txt.php @ 3318

Last change on this file since 3318 was 3318, checked in by bsittler, 11 years ago

add a reset button, move usage to "stdout", and stop hyperlinking the
logo filename in the example

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