File Coverage

blib/lib/Image/IPTCInfo/RasterCaption.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Image::IPTCInfo::RasterCaption;
2            
3 4     4   2502 use vars qw/$VERSION/;
  4         6  
  4         307  
4             $VERSION = 0.1;
5            
6             =head1 NAME
7            
8             Image::IPTCInfo::RasterCaption - get/set IPTC raserized caption w/Image::Magick
9            
10             =head1 SYNOPSIS
11            
12             use Image::IPTCInfo::RasterCaption;
13            
14             # Access the raw rasterized caption field:
15             $info = new Image::IPTCInfo::RasterCaption
16             ('C:/new_caption.jpg')
17             or die "No raster caption!";
18             $raw_raster_caption = $info->Attribute('rasterized caption');
19            
20             ...
21            
22             =head1 DESCRIPTION
23            
24             Add to C support for the IPTC IIM4
25             Dataset 2:125 Rasterized Caption.
26            
27             This is an alpha-state module that sub-classes Josh Carter's
28             C, and you should consult the L
29             for details of how to use it before proceding with this documentation.
30            
31             This module will loose its alpha status once I've verified
32             it matches the IPTC standard. If anyone has a rasterized
33             caption not produced by this module, please send me a copy!
34            
35             =head1 BACKGROUND
36            
37             The IPTC is the International Press & Telecommunications Council.
38             The IIM4 is version four of the Information Interchange Model,
39             which amongst other things allows the embedding of text (and now
40             XML) within images (though XML support is not yet provided by
41             the Perl modules in this namespace).
42            
43             The IPTC IIM4 specification describes a rasterized caption as
44             containing "...the rasterized object data description and is used
45             where characters that have not been coded are required for
46             the caption."
47            
48             Not repeatable, 7360 octets, consisting of binary data,one bit
49             per pixel,two value bitmap where 1 (one) represents black and
50             0 (zero) represents white.
51            
52             -- IPTC-NAA Information Interchange Model Version No. 4,
53             October 1997, Page 41
54            
55            
56             =cut
57            
58 4     4   9551 use Image::Magick;
  0            
  0            
59             use Image::IPTCInfo;
60             push @ISA, 'Image::IPTCInfo';
61            
62             use Carp;
63             use strict;
64            
65             # Add the rasterized caption to the Image::IPTCInfo dataset
66             $Image::IPTCInfo::datasets{125} = 'rasterized caption';
67             $Image::IPTCInfo::RasterCpation::datasets{125} = 'rasterized caption';
68            
69            
70             #
71             # SUB _blank_canvas
72             # Returns a plain white canvas of the standard size
73             #
74             sub _blank_canvas {
75             my $image = new Image::Magick;
76             $image = Image::Magick->new;
77             $image->Set(size=>'460x128');
78             $image->ReadImage('xc:white');
79             return $image;
80             }
81            
82            
83             #
84             # SUB _get_raster_caption
85             # ACCEPTS an image magick object and threshold value.
86             # RETURNS a scalar representing the bits
87             # of a rasterized caption extracted from
88             # the field of the same name.
89             #
90             sub _get_raster_caption { my ($image,$threshold)=(shift,shift);
91             my $iptc='';
92             for (my $x=0; $x<460; $x++){
93             for (my $y=127; $y>=0; $y--){
94             my ($r,$g,$b,$ugh) = split',',$image->Get( "pixel[$x,$y]" );
95             if ($r<$threshold){
96             $iptc.="1";
97             # print "1";
98             } else {
99             $iptc.="0";
100             # print " ";
101             }
102             }
103             # print "\n";
104             }
105             return pack('B*', $iptc)
106             }
107            
108            
109             =head1 METHOD save_raster_caption
110            
111             Writes to the file specified in the sole argument
112             the rasterized caption stored in the object's IPTC
113             field of the same name.
114            
115             Image creation is via C so see L
116             for further details.
117            
118             On failure returns C.
119            
120             On success returns the path written to.
121            
122             =cut
123            
124             sub save_raster_caption { my ($self,$path) = (shift, shift);
125             croak "No path!" if not $path;
126             if (not $self->{_data}->{"rasterized caption"}){
127             carp "No rasterized caption data availabel";
128             return undef;
129             }
130             my $image = &_blank_canvas;
131             my $rc = unpack( 'B*', $self->{_data}->{"rasterized caption"} );
132             my $o=-1; # Offset for reading IPTC field
133             for (my $x=0; $x<460; $x++){
134             for (my $y=127; $y>=0; $y--){
135             ++$o;
136             if (substr($rc,$o,1)==1){
137             $image->Set("pixel[$x,$y]"=>'black');
138             }
139             }
140             }
141             my $err = $image->Write($path);
142             if ($err){
143             carp "Could not write to file $path: $err / $!";
144             return undef;
145             }
146             return $path;
147             }
148            
149            
150            
151             =head1 METHOD load_raster_caption
152            
153             Sets the IPTC field 'rasterized caption' with
154             a rasterized version of the image located at
155             the path specified in the first argument.
156            
157             If a second argument is provided, it should be
158             an integer in the range 1-255, representing the
159             threshold at which source image pixels will be
160             included in the rasterized monochrome. The default
161             is 127.
162            
163             If the image is larger than the standard size,
164             it will be resized. No attempt is made to maintain
165             its aspect ratio, though if there is a demand for
166             this I shall add it.
167            
168             On failure carps and returns C.
169            
170             On success returns a referemce to a scalar containing
171             the rasterized caption.
172            
173             =cut
174            
175             sub load_raster_caption { my ($self,$path,$threshold) = (shift, shift,shift);
176             croak "load_raster_caption requires a 'path' paramter" if not $path;
177             $threshold = 127 if not defined $threshold;
178             croak "Threshold param must be 1-255" if $threshold<1 or $threshold>255;
179             my $image = new Image::Magick;
180             my $err = $image->Read($path);
181             if ($err){
182             carp "Could not read file $path: $!";
183             return undef;
184             }
185             $image->Quantize(colorspace=>'gray');
186             $image->Set("monochrome"=>1);
187             $image->Resize(geometry=>'460x128');
188             my $iptc = _get_raster_caption($image,$threshold);
189             $self->SetAttribute('rasterized caption', $iptc);
190             return \$iptc;
191             }
192            
193            
194            
195            
196             =head1 METHOD set_raster_caption
197            
198             Fills the rasterized caption with binary data representing
199             supplied text.
200            
201             This is very elementry: no font metrics what so ever,
202             just calls C's C
203             with the text supplied in the first argument, using the
204             point size specified in the second argument, and the font
205             named in the third.
206            
207             If no size is supplied, defaults to 12 points.
208            
209             If no font is supplied, then C is looked
210             for in the C directory beneath the directory specified
211             in the environment variable C. Failing that, the
212             ImageMagick default is used - YMMV. See the I method
213             in L (C) for details.
214            
215             On failure carps and returns C
216            
217             On success returns a referemce to a scalar containing
218             the rasterized caption.
219            
220             =cut
221            
222             sub set_raster_caption { my ($self,$text,$size,$font) = (@_);
223             my $image = &_blank_canvas;
224             if (not $font and -e "$ENV{SYSTEMROOT}/Fonts/Arialuni.TTF"){
225             $font = "$ENV{SYSTEMROOT}/Fonts/Arialuni.TTF";
226             }
227             my $err = $image->Annotate(
228             font => $font,
229             y => 40,
230             pointsize => $size || 12,
231             fill => 'black',
232             text => $text
233             );
234             if ($err){
235             carp "Image Magick error: $err";
236             return undef;
237             }
238             my $rc = _get_raster_caption ($image,127);
239             $self->SetAttribute('rasterized caption', $rc);
240             # $image->Write('c:/text.jpg');
241             return \$rc;
242             }
243            
244            
245             1;
246             __END__