1NAME 2 Image::Scale - Fast, high-quality fixed-point image resizing 3 4SYNOPSIS 5 use Image::Scale 6 7 # Resize to 150 width and save to a file 8 my $img = Image::Scale->new('image.jpg') || die "Invalid JPEG file"; 9 $img->resize_gd( { width => 150 } ); 10 $img->save_jpeg('resized.jpg'); 11 12 # Easily resize artwork embedded within an audio file 13 # You can use L<Audio::Scan> to obtain offset/length information 14 my $img = Image::Scale->new( 'track.mp3', { offset => 2200, length => 34123 } ); 15 $img->resize_gd_fixed_point( { width => 75, height => 75, keep_aspect => 1 } ); 16 my $data = $img->as_png(); 17 18DESCRIPTION 19 This module implements several resizing algorithms with a focus on low 20 overhead, speed and minimal features. Algorithms available are: 21 22 GD's copyResampled (floating-point) 23 GD's copyResampled fixed-point (useful on embedded devices/NAS devices) 24 GraphicsMagick's assortment of resize filters (floating-point) 25 GraphicsMagick's Triangle filter in fixed-point 26 27 Supported image formats include JPEG, GIF, PNG, and BMP for input, and 28 JPEG and PNG for output. 29 30 This module came about because we needed to improve the very slow 31 performance of floating-point resizing algorithms on platforms without a 32 floating-point unit, such as ARM devices like the SheevaPlug, and the 33 Sparc-based ReadyNAS Duo. Previously it would take many seconds to 34 resize using GD on the ReadyNAS but the conversion to fixed-point with a 35 little assembly code brings this down to the range of well under 1 36 second. 37 38 Normal platforms will also see improvement, by removing all of the GD 39 overhead this version of copyResampled is around 3 times faster while 40 also using less memory. 41 42 The fixed-point versions have an accuracy to around 4 decimal places so 43 the quality of floating-point vs. fixed is essentially identical. 44 45METHODS 46 new( $PATH or \$DATA, [ \%OPTIONS ] ) 47 Initialize a new Image::Scale object from PATH, which may be any valid 48 JPEG, GIF, PNG, or BMP file. 49 50 Raw image data may also be passed in as a scalar reference. Using a file 51 path is recommended when possible as this is more efficient and requires 52 less memory. 53 54 new() reads the image header, and will return undef if the header is 55 invalid, so be sure to check for this. 56 57 Optionally you can also pass in additional options in a hashref: 58 59 offset 60 length 61 62 To access an image embedded within another file, such as an audio file, 63 you can specify a byte offset and length. 64 65 width() 66 Returns the width of the original source image. 67 68 height() 69 Returns the height of the original source image. 70 71 resize( \%OPTIONS ) 72 resize() uses the default resize algorithm, which is 73 resize_gd_fixed_point. See below for details on the available options. 74 75 resize_gd( \%OPTIONS ) 76 resize_gd_fixed_point( \%OPTIONS ) 77 resize_gm( \%OPTIONS ) 78 resize_gm_fixed_point( \%OPTIONS ) 79 The 4 resize methods available are: 80 81 resize_gd - This is GD's copyResampled algorithm (floating-point) 82 resize_gd_fixed_point - copyResampled (converted to fixed-point) 83 resize_gm - GraphicsMagick, see below for filter options 84 resize_gm_fixed_point - GraphicsMagick, only the Triangle filter is available in fixed-point mode 85 86 Options are specified in a hashref: 87 88 width 89 height 90 91 At least one of width or height are required. If only one is supplied 92 the image will retain the original aspect ratio. 93 94 filter 95 96 For use with resize_gm() only. Choose from the following filters, sorted 97 in order from least to most CPU time. This does not necessarily mean 98 least to best quality, though! Be sure to do your own comparisons for 99 quality. 100 101 Point 102 Box 103 Triangle 104 Hermite 105 Hanning 106 Hamming 107 Blackman 108 Gaussian 109 Quadratic 110 Cubic 111 Catrom 112 Mitchell 113 Lanczos 114 Bessel 115 Sinc 116 117 If no filter is specified the default is Lanczos if downsizing, and 118 Mitchell for upsizing or if the image has an alpha channel. 119 120 keep_aspect => 1 121 122 Only useful when both width and height are specified. This option will 123 keep the original aspect ratio of the source as well as center the image 124 when resizing into a different aspect ratio. For best results, images 125 altered in this way should be saved as PNG which will automatically add 126 the necessary transparency around the image. 127 128 bgcolor => 0xffffff 129 130 When using keep_aspect, you can use bgcolor to define the background 131 color of the padded portion of the image. Usually this should only be 132 used if saving as JPEG because PNG will default to transparent. If this 133 value is set and the image is saved as PNG, the PNG will not be 134 transparent. The default bgcolor value is 0x000000 (black). 135 136 ignore_exif => 1 137 138 By default, if a JPEG image contains an EXIF tag with orientation info, 139 the image will be rotated accordingly during resizing. To disable this 140 feature, set ignore_exif to 1. 141 142 memory_limit => $limit_in_bytes 143 144 To avoid excess memory growth when resizing images that may be very 145 large, you can specify this option. If the resize_*() method would 146 result in a total memory allocation greater than $limit_in_bytes, the 147 method will die. Be sure to wrap the resize call in an eval when using 148 this option. 149 150 save_jpeg( $PATH, [ $QUALITY ] ) 151 Saves the resized image as a JPEG to PATH. If a quality is not 152 specified, the quality defaults to 90. 153 154 as_jpeg( [ $QUALITY ] ) 155 Returns the resized JPEG image as scalar data. If a quality is not 156 specified, the quality defaults to 90. 157 158 save_png( $PATH ) 159 Saves the resized image as a PNG to PATH. Transparency is preserved when 160 saving to PNG. 161 162 as_png() 163 Returns the resized PNG image as scalar data. 164 165 jpeg_version() 166 png_version() 167 gif_version() 168 Returns the version of the image library used. Returns undef if support 169 for that image format was not built. 170 171PERFORMANCE 172 These numbers were gathered on my 2.4ghz MacBook Pro. 173 174 JPEG image, 1425x1425 -> 200x200 (libjpeg v8 with scaling) 175 176 GD copyResampled 21.9/s 177 resize_gm( { filter => 'Triangle' } ) 65.7/s 178 resize_gd_fixed_point 67.9/s 179 resize_gd 69.4/s 180 resize_gm_fixed_point 74.5/s 181 182 PNG image, 512x768 -> 200x133 (libpng 1.4.3) 183 184 GD copyResampled 14.7/s 185 resize_gm( { filter => 'Triangle' } ) 26.2/s 186 resize_gm_fixed_point 27.7/s 187 resize_gd 29.9/s 188 resize_gd_fixed_point 31.9/s 189 190 Here are some numbers from a machine without floating-point support. 191 (Marvell SheevaPlug 1.2ghz ARM9, JPEG 1425x1425 -> 200x200, libjpeg 6b 192 with scaling) 193 194 GD copyResampled 1.08/s 195 resize_gd 2.16/s 196 resize_gm( { filter => 'Triangle' } ) 2.85/s 197 resize_gd_fixed_point 7.98/s 198 resize_gm_fixed_point 9.44/s 199 200 And finally, from an even slower machine, the 240mhz Netgear ReadyNAS 201 Duo which has extremely poor floating-point performance. (JPEG 1425x1425 202 -> 200x200, libjpeg 6b with scaling) 203 204 resize_gd 0.029/s (34.5 s/iter) 205 resize_gm( { filter => 'Triangle' } ) 0.033/s (30.4 s/iter) 206 resize_gd_fixed_point 1.92/s (0.522 s/iter) 207 resize_gm_fixed_point 2.07/s (0.483 s/iter) (63x faster than floating-point!) 208 209SEE ALSO 210 TODO 211 212AUTHOR 213 Andy Grundman, <andy@hybridized.org> 214 215COPYRIGHT AND LICENSE 216 Copyright (C) 2010 Andy Grundman 217 218 This program is free software; you can redistribute it and/or modify it 219 under the terms of the GNU General Public License as published by the 220 Free Software Foundation; either version 2 of the License, or (at your 221 option) any later version. 222 223