Aleksander Machniak
2012-05-22 041c93ce0bc00cb6417ce2e4bdce2ed84d37f50a
commit | author | age
a71a97 1 <?php
A 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_image.php                                       |
6  |                                                                       |
7  | This file is part of the Roundcube Webmail client                     |
8  | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
9  | Copyright (C) 2011-2012, Kolab Systems AG                             |
10  |                                                                       |
11  | Licensed under the GNU General Public License version 3 or            |
12  | any later version with exceptions for skins & plugins.                |
13  | See the README file for a full license statement.                     |
14  |                                                                       |
15  | PURPOSE:                                                              |
16  |   Image resizer                                                       |
17  |                                                                       |
18  +-----------------------------------------------------------------------+
19  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
20  | Author: Aleksander Machniak <alec@alec.pl>                            |
21  +-----------------------------------------------------------------------+
22 */
23
24 class rcube_image
25 {
26     private $image_file;
27
28     function __construct($filename)
29     {
30         $this->image_file = $filename;
31     }
32
33     /**
34      * Get image properties.
35      *
36      * @return mixed Hash array with image props like type, width, height
37      */
38     public function props()
39     {
f5a7e1 40         // use GD extension
a71a97 41         if (function_exists('getimagesize') && ($imsize = @getimagesize($this->image_file))) {
A 42             $width   = $imsize[0];
43             $height  = $imsize[1];
44             $gd_type = $imsize['2'];
45             $type    = image_type_to_extension($imsize['2'], false);
46         }
47
f5a7e1 48         // use ImageMagick
A 49         if (!$type && ($data = $this->identify())) {
50             list($type, $width, $height) = $data;
a71a97 51         }
A 52
53         if ($type) {
54             return array(
55                 'type'    => $type,
56                 'gd_type' => $gd_type,
57                 'width'   => $width,
58                 'height'  => $height,
59             );
60         }
61     }
62
63     /**
64      * Resize image to a given size
65      *
66      * @param int    $size      Max width/height size
67      * @param string $filename  Output filename
68      *
69      * @return Success of convert as true/false
70      */
71     public function resize($size, $filename = null)
72     {
be98df 73         $result  = false;
A 74         $rcube   = rcube::get_instance();
b1b808 75         $convert = $rcube->config->get('im_convert_path', false);
be98df 76         $props   = $this->props();
a71a97 77
A 78         if (!$filename) {
79             $filename = $this->image_file;
80         }
81
82         // use Imagemagick
83         if ($convert) {
84             $p['out']  = $filename;
85             $p['in']   = $this->image_file;
86             $p['size'] = $size.'x'.$size;
f5a7e1 87             $type      = $props['type'];
a71a97 88
f5a7e1 89             if (!$type && ($data = $this->identify())) {
A 90                 $type = $data[0];
a71a97 91             }
A 92
93             $type = strtr($type, array("jpeg" => "jpg", "tiff" => "tif", "ps" => "eps", "ept" => "eps"));
94             $p += array('type' => $type, 'types' => "bmp,eps,gif,jp2,jpg,png,svg,tif", 'quality' => 75);
95             $p['-opts'] = array('-resize' => $size.'>');
96
97             if (in_array($type, explode(',', $p['types']))) { // Valid type?
be98df 98                 $result = rcube::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p) === '';
a71a97 99             }
A 100
101             if ($result) {
102                 return true;
103             }
104         }
105
106         // use GD extension
107         $gd_types = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG);
108         if ($props['gd_type'] && in_array($props['gd_type'], $gd_types)) {
109             if ($props['gd_type'] == IMAGETYPE_JPEG) {
110                 $image = imagecreatefromjpeg($this->image_file);
111             }
112             elseif($props['gd_type'] == IMAGETYPE_GIF) {
113                 $image = imagecreatefromgif($this->image_file);
114             }
115             elseif($props['gd_type'] == IMAGETYPE_PNG) {
116                 $image = imagecreatefrompng($this->image_file);
117             }
118
119             $scale  = $size / max($props['width'], $props['height']);
120             $width  = $props['width']  * $scale;
121             $height = $props['height'] * $scale;
122
123             $new_image = imagecreatetruecolor($width, $height);
124
125             // Fix transparency of gif/png image
126             if ($props['gd_type'] != IMAGETYPE_JPEG) {
127                 imagealphablending($new_image, false);
128                 imagesavealpha($new_image, true);
129                 $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
130                 imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
131             }
132
133             imagecopyresampled($new_image, $image, 0, 0, 0, 0, $width, $height, $props['width'], $props['height']);
134             $image = $new_image;
135
136             if ($props['gd_type'] == IMAGETYPE_JPEG) {
137                 $result = imagejpeg($image, $filename, 75);
138             }
139             elseif($props['gd_type'] == IMAGETYPE_GIF) {
140                 $result = imagegif($image, $filename);
141             }
142             elseif($props['gd_type'] == IMAGETYPE_PNG) {
143                 $result = imagepng($image, $filename, 6, PNG_ALL_FILTERS);
144             }
145
146             if ($result) {
147                 return true;
148             }
149         }
150
151
152         // @TODO: print error to the log?
153         return false;
154     }
155
f5a7e1 156     /**
A 157      * Identify command handler.
158      */
159     private function identify()
160     {
be98df 161         $rcube = rcube::get_instance();
f5a7e1 162
be98df 163         if ($cmd = $rcube->config->get('im_identify_path')) {
f5a7e1 164             $args = array('in' => $this->image_file, 'format' => "%m %[fx:w] %[fx:h]");
be98df 165             $id   = rcube::exec($cmd. ' 2>/dev/null -format {format} {in}', $args);
f5a7e1 166
A 167             if ($id) {
168                 return explode(' ', strtolower($id));
169             }
170         }
171     }
a71a97 172 }