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

Last change on this file since 3310 was 3310, checked in by bsittler, 12 years ago

now works as HTML

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