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

Last change on this file since 4148 was 4148, checked in by Sam Hocevar, 10 years ago

Update my e-mail address everywhere.

  • Property svn:keywords set to Id
File size: 13.0 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@hocevar.net>
9 *                2007 Jean-Yves Lamoureux <jylam@lnxscene.org>
10 *                All Rights Reserved
11 *
12 *  $Id: img2txt.php 4148 2009-12-19 14:38:38Z sam $
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@hocevar.net> <jylam@lnxscene.org>\n" .
260        "          <bsittler@gmail.com> Version: %s\n" .
261        "\n" .
262        "img2txt, along with its documentation, may be freely copied and distributed.\n" .
263        "\n" .
264        "The latest version of img2txt is available from the web site,\n" .
265        "        http://caca.zoy.org/wiki/libcaca in the libcaca package.\n" .
266        "\n",
267        caca_get_version());
268}
269function main()
270{
271        global $file, $filename;
272        global $argc, $argv;
273        global $stderr;
274        $cols = 0;
275        $lines = 0;
276        $font_width = 6;
277        $font_height = 10;
278        $format = NULL;
279        $dither = NULL;
280        $gamma = $brightness = $contrast = -1.0;
281
282        $long_options = array(
283                "width:"        => 'W',
284                "height:"       => 'H',
285                "font-width:"   => 'x',
286                "font-height:"  => 'y',
287                "format:"       => 'f',
288                "dither:"       => 'd',
289                "gamma:"        => 'g',
290                "brightness:"   => 'b',
291                "contrast:"     => 'c',
292                "help"          => 'h',
293                "version"       => 'v'
294                );
295
296        try {
297                while($opt_and_arg = mygetopt("W:H:f:d:g:b:c:hvx:y:", array_keys($long_options)))
298                {
299                        $opt = $opt_and_arg[0];
300                        $arg = $opt_and_arg[1];
301                        if((substr($opt, 0, 2) == '--')
302                                &&
303                                array_key_exists(substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : ''), $long_options))
304                        {
305                                $opt = '-' . $long_options[substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : '')];
306                        }
307                        switch($opt)
308                        {
309                        case '-W': /* --width */
310                                $cols = intval($arg);
311                                break;
312                        case '-H': /* --height */
313                                $lines = intval($arg);
314                                break;
315                        case '-x': /* --width */
316                                $font_width = intval($arg);
317                                break;
318                        case '-y': /* --height */
319                                $font_height = intval($arg);
320                                break;
321                        case '-f': /* --format */
322                                $format = $arg;
323                                break;
324                        case '-d': /* --dither */
325                                $dither = $arg;
326                                break;
327                        case '-g': /* --gamma */
328                                $gamma = floatval($arg);
329                                break;
330                        case '-b': /* --brightness */
331                                $brightness = floatval($arg);
332                                break;
333                        case '-c': /* --contrast */
334                                $contrast = floatval($arg);
335                                break;
336                        case '-h': /* --help */
337                                usage($argc, $argv);
338                                return 0;
339                        case '-v': /* --version */
340                                version();
341                                return 0;
342                        default:
343                                return 1;
344                        }
345                }
346        }
347        catch (MygetoptException $e)
348        {
349                $stderr .= $argv[0] . ": " . $e->getMessage() . "\n";
350                usage($argc, $argv);
351                return 2;
352        }
353
354        if((! $file) && ($argc == 2) && ($argv[1] == 'logo-caca.png'))
355        {
356                $file = 'logo-caca.png';
357                $argc = 1;
358        }
359        else if($filename && $file && ($argc == 2)
360                        &&
361                        (strtolower(basename($argv[1])) == strtolower(basename($filename))))
362        {
363                $argc = 1;
364        }
365
366        if($argc == 2)
367        {
368                $stderr .= sprintf("%s: image not found\n", $argv[1]);
369                return 1;
370        }
371
372        if($argc > 2)
373        {
374                $stderr .= sprintf("%s: too many arguments\n", $argv[0]);
375                usage($argc, $argv);
376                return 1;
377        }
378
379        if(! $file)
380        {
381                $stderr .= sprintf("%s: no image was provided\n", $argv[0]);
382                usage($argc, $argv);
383                return 1;
384        }
385
386        $cv = caca_create_canvas(0, 0);
387        if(!$cv)
388        {
389                $stderr .= sprintf("%s: unable to initialise libcaca\n", $argv[0]);
390                return 1;
391        }
392
393        $i_str = $file ? file_get_contents($file) : NULL;
394        $i = $i_str ? imagecreatefromstring($i_str) : NULL;
395        if(!$i)
396        {
397                $stderr .= sprintf("%s: unable to load %s\n", $argv[0], $filename);
398                return 1;
399        }
400
401        /* Assume a 6×10 font */
402        if(!$cols && !$lines)
403        {
404                $cols = 60;
405                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
406        }
407        else if($cols && !$lines)
408        {
409                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
410        }
411        else if(!$cols && $lines)
412        {
413                $cols = $lines * imagesx($i) * $font_height / imagesy($i) / $font_width;
414        }
415
416
417        caca_set_canvas_size($cv, $cols, $lines);
418        caca_set_color_ansi($cv, CACA_DEFAULT, CACA_TRANSPARENT);
419        caca_clear_canvas($cv);
420        $i_dither = caca_create_dither($i);
421        if(! caca_set_dither_algorithm($i_dither, $dither?$dither:"fstein"))
422        {
423                $stderr .= sprintf("%s: Can't dither image with algorithm '%s'\n", $argv[0], $dither?$dither:"fstein");
424                return -1;
425        }
426
427        if($brightness!=-1) caca_set_dither_brightness ($i_dither, $brightness);
428        if($contrast!=-1) caca_set_dither_contrast ($i_dither, $contrast);
429        if($gamma!=-1) caca_set_dither_gamma ($i_dither, $gamma);
430
431        caca_dither_bitmap($cv, 0, 0, $cols, $lines, $i_dither, $i);
432
433        $format = $format ? $format : 'html';
434
435        $export = caca_export_string($cv, $format);
436        if(!$export)
437        {
438                $stderr .= sprintf("%s: Can't export to format '%s'\n", $argv[0], $format);
439                return -1;
440        }
441        else
442        {
443                $content_type_map = array(
444                        'ansi' => 'text/plain; charset=CP437',
445                        'utf8' => 'text/plain; charset=UTF-8',
446                        'utf8cr' => 'text/plain; charset=UTF-8',
447                        'html' => 'text/html; charset=UTF-8',
448                        'html3' => 'text/html; charset=UTF-8',
449                        'bbfr' => 'text/plain; charset=UTF-8',
450                        'irc' => 'text/plain; charset=UTF-8',
451                        'ps' => 'application/postscript',
452                        'svg' => 'image/svg+xml',
453                        'tga' => 'image/x-targa'
454                        );
455
456                $download_extension_map = array(
457                        'caca' => 'caca',
458                        'ansi' => 'txt',
459                        'utf8' => 'txt',
460                        'utf8cr' => 'txt',
461                        'irc' => 'txt',
462                        'tga' => 'tga'
463                        );
464
465                $inline_extension_map = array(
466                        'bbfr' => 'txt',
467                        'ps' => 'ps',
468                        'svg' => 'svg'
469                        );
470
471                if (! array_key_exists($format, $content_type_map))
472                        $content_type = 'application/octet-stream';
473                else
474                        $content_type = $content_type_map[$format];
475
476                header('Content-Type: ' . $content_type);
477                if (array_key_exists($format, $download_extension_map))
478                        header('Content-Disposition: attachment; filename=export.' . $download_extension_map[$format]);
479                else if (array_key_exists($format, $inline_extension_map))
480                        header('Content-Disposition: inline; filename=export.' . $inline_extension_map[$format]);
481
482                echo $export;
483        }
484
485        return 0;
486}
487$ret = 1;
488if(isset($_REQUEST['args']) || $file)
489{
490        $ret = main();
491}
492if($ret || strlen($stdout) || strlen($stderr))
493{
494        header('Content-Type: text/html; charset=UTF-8');
495        ?>
496<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
497    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
498
499<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
500<head>
501<title>image to text converter</title>
502<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
503</head>
504<body>
505<form id="img2txtform" name="img2txtform" action="#" enctype="multipart/form-data" method="post">
506<label for="file">Image:</label>
507<input id="file" name="file" type="file" />
508<br />
509<label for="args">Options:</label>
510<input id="args" name="args" type="text" value="<?= isset($_REQUEST['args']) ? htmlspecialchars($_REQUEST['args']) : '' ?>" size="80" />
511<br />
512<input type="submit" /> <input type="reset" />
513</form>
514<?php
515                ;
516        if(strlen($stderr))
517        {
518                ?><pre xml:space="preserve"><strong><?= htmlspecialchars($stderr) ?></strong></pre><?php
519                        ;
520        }
521        if(strlen($stdout))
522        {
523                ?><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
524                        ;
525        }
526        ?>
527</body>
528</html>
529<?php
530                ;
531}
532?>
Note: See TracBrowser for help on using the repository browser.