📄 ch13_05.htm
字号:
by Image::Magick without LZW compression will be much larger than atypical GIF, and a JPEG may not capture sharp details such asstraight lines and text found in a graph as accurately <a name="INDEX-2667" /> <a name="INDEX-2,668" />as<a name="INDEX-2669" />a PNG.</p></div><a name="ch13-21-fm2xml" /><div class="sect2"><h3 class="sect2">13.5.3. PDF and PostScript Support</h3><p>If you look through the list <a name="INDEX-2670" />of formats that<a name="INDEX-2671" />Image::Magick supports, you will seePDF and <a name="INDEX-2672" /><a name="INDEX-2673" />PostScript listed among others. IfGhostScript is present, Image::Magick can read and write to theseformats, and it allows you to access individual pages.</p><p>The following code joins two separate PDF files:</p><blockquote><pre class="code">my $magick = new Image::Magick( format => "pdf" );$status = $magick->Read( "cover.pdf", "newsletter.pdf" );warn "Read failed: $status" if $status;$status = $magick->Write( "pdf:combined.pdf" );warn "Write failed: $status" if $status;</pre></blockquote><p>However, keep in mind that Image::Magick is an image manipulationtool. It can read PDF and PostScript using GhostScript, but itrasterizes these formats, converting any text and vector elementsinto images. Likewise, when it writes to these formats, it writeseach page as an image encapsulated in PDF and PostScript formats.</p><p>Therefore, if you attempt to open a large PDF or PostScript file withImage::Magick, it will take a very long time as it rasterizes eachpage. If you then save this file, the result will have lost all ofits text and vector information. It may look the same on the screen,but it will print much worse. The resulting file will likely be muchlarger, and text cannot be highlighted or searched because it hasbeen converted <a name="INDEX-2674" /> <a name="INDEX-2,675" />to an image.</p></div><a name="ch13-22-fm2xml" /><div class="sect2"><h3 class="sect2">13.5.4. Image Processing</h3><p>Typically, if you need to create a new image, you should use<a name="INDEX-2676" /> <a name="INDEX-2,677" /> <a name="INDEX-2,678" /> <a name="INDEX-2,679" />GD. It'ssmaller and more efficient. However, Image::Magick providesadditional effects that GD does not support, such as blur.Let's take a look at <a href="ch13_05.htm#ch13-69440">Example 13-6</a>, whichcontains a CGI script that uses some of Image::Magick'sfeatures to create a <a name="INDEX-2680" /> <a name="INDEX-2,681" />text banner with a drop shadow, as seenin <a href="ch13_05.htm#ch13-66556">Figure 13-12</a>.</p><a name="ch13-69440" /><div class="example"><h4 class="objtitle">Example 13-6. shadow_text.cgi </h4><a name="INDEX-2682" /><blockquote><pre class="code">#!/usr/bin/perl -wTuse strict;use CGI;use Image::Magick;use constant FONTS_DIR => "/usr/local/httpd/fonts";my $q = new CGI;my $font = $q->param( "font" ) || 'cetus';my $size = $q->param( "size" ) || 40;my $string = $q->param( "text" ) || 'Hello!';my $color = $q->param( "color" ) || 'black';$font =~ s/\W//g;$font = 'cetus' unless -e FONTS_DIR . "/$font.ttf";my $image = new Image::Magick( size => '500x100' );$image->Read( 'xc:white' );$image->Annotate( font => "\@@{[ FONTS_DIR ]}/$font.ttf", pen => 'gray', pointsize => $size, gravity => 'Center', text => $string );$image->Blur( 100 );$image->Roll( "+5+5" );$image->Annotate( font => "\@@{[ FONTS_DIR ]}/$font.ttf", pen => $color, pointsize => $size, gravity => 'Center', text => $string );binmode STDOUT;print $q->header( "image/jpeg" );$image->Write( "jpeg:-" );</pre></blockquote></div><a name="ch13-66556" /><div class="figure"><img width="193" src="figs/cgi2.1312.gif" height="42" alt="Figure 13-12" /></div><h4 class="objtitle">Figure 13-12. ImageMagick and FreeType in action</h4><p>This CGI script indirectly uses the<em class="emphasis">FreeType</em><a name="INDEX-2683" /> <a name="INDEX-2,684" /><a name="INDEX-2685" /> <a name="INDEX-2,686" /> library, which allows us to use TrueTypefonts within our image. TrueType is a scalable font file formatdeveloped by Apple and Microsoft, and is supported natively on boththe MacOS and Windows. As a result, we can pick and choose from thethousands of TrueType fonts freely available on the Internet tocreate our headlines. If you do not have FreeType, you cannot useTrueType fonts with Image::Magick; you can obtain FreeType from<a href="http://www.freetype.org/">http://www.freetype.org/</a>.</p><p>The first step we need to perform before we can use this CGIapplication is to obtain TrueType fonts and place them in thedirectory specified by the<a name="INDEX-2687" /><tt class="literal">FONTS_DIR</tt>constant. The best way to locate <a name="INDEX-2688" />font repositories is to use asearch engine; search for "free AND TrueType AND fonts".If you're curious, the font we used to create a typewritereffect, in <a href="ch13_03.htm#ch13-31232">Figure 13-1</a>, is<em class="emphasis">Cetus</em>, which is included with the GD::Textmodule.</p><p>Now let's look at the code. We accept four fields:<em class="emphasis">font</em>, <em class="emphasis">size</em>,<em class="emphasis">text,</em> and <em class="emphasis">color</em>, whichgovern how the banner image will be rendered. If we don'treceive values for any of these fields, we set default values.</p><p>As you can see, we have no corresponding user interface (i.e., form)from which the user passes this information to the application.Instead, this application is intended to be used with the<<a name="INDEX-2689" /><a name="INDEX-2690" />IMG>tag, like so:</p><blockquote><pre class="code"><IMG SRC="/cgi/shadow_text.cgi?font=cetus &size=40 &color=black &text=I%20Like%20CGI"></pre></blockquote><p>The query information above is aligned so you can see what fields theapplication accepts. Normally, you would pass the entire queryinformation in one line. Since this application creates a JPEG imageon the fly, we can use it to embed dynamic text banners in otherwise<a name="INDEX-2691" /><a name="INDEX-2692" /> <a name="INDEX-2,693" />static HTMLdocuments.</p><p>We use the font name, as passed to us, to find the font file in the<tt class="literal">FONTS_DIR</tt> directory. To be safe, we strip non-wordcharacters and test for the existence of a<a name="INDEX-2694" /><a name="INDEX-2695" /><a name="INDEX-2696" />font with that name in our<tt class="literal">FONTS_DIR</tt> directory, using the<em class="emphasis">-e</em> operator, before passing its full path to<em class="emphasis">ImageMagick</em>.</p><p>Now, we're ready to create the image. First, we create a newinstance of the Image::Magick object, passing to it the image size of500 × 100 pixels. Next, we use the <em class="emphasis">Read</em>method to create a canvas with a white background. Now, we'reready to draw the text banner onto the image. If you look back at<a href="ch13_05.htm#ch13-66556">Figure 13-12</a>, you'll see a banner with a dropshadow. When we construct the image, we draw the drop shadow first,followed by the dark top text layer.</p><p>We use the <em class="emphasis">Annotate</em> method, with a number ofarguments to render the gray drop shadow. The path to the font filerequires a <em class="emphasis">@</em><a name="INDEX-2697" /><a name="INDEX-2698" /><a name="INDEX-2699" /> <a name="INDEX-2,700" /> prefix. But, since Perl does not allowus to have a literal <em class="emphasis">@</em> character within a<a name="INDEX-2701" /><a name="INDEX-2702" /><a name="INDEX-2703" />double=quoted string, we have to escape itby preceding it with the <em class="emphasis">\</em> character.</p><p>Once we've drawn the drop shadow, it's time to apply ablur effect by invoking the <em class="emphasis">Blur</em> method. Thiscreates the effect that the text is floating underneath the solidlayer of text. The <em class="emphasis">Blur</em> method requires apercentage value, and since we want a full blur, we choose a value of100. A value greater than 100% produces an undesirable, washed outeffect.</p><p>Our next step is to move the <a name="INDEX-2704" />drop shadow horizontally andvertically a bit. We achieve this by calling the<em class="emphasis">Roll</em> method, and pass it the value of"+5+5"; right and down shift by five pixels. Now,we're ready to draw the solid top text. Again, we invoke the<em class="emphasis">Annotate</em> method to render the text, but thistime around, we change the pen color to reflect the user'schoice. We're done with the drawing and can send it to thebrowser.</p><p>Finally, we enable<em class="emphasis">binmode</em><a name="INDEX-2705" /><a name="INDEX-2706" />, send acontent type of<em class="emphasis">image/jpeg</em><a name="INDEX-2707" />, and call the <em class="emphasis">Write</em><a name="INDEX-2708" /><a name="INDEX-2709" /><a name="INDEX-2710" />method tosend the JPEG image <a name="INDEX-2711" /> <a name="INDEX-2,712" /> <a name="INDEX-2,713" /> <a name="INDEX-2,714" />to the standard <a name="INDEX-2,715" /> <a name="INDEX-2,716" />output stream.</p></div><hr align="left" width="515" /><div class="navbar"><table border="0" width="515"><tr><td width="172" valign="top" align="left"><a href="ch13_04.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td width="171" valign="top" align="center"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0" /></a></td><td width="172" valign="top" align="right"><a href="ch14_01.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr><tr><td width="172" valign="top" align="left">13.4. Additional GD Modules</td><td width="171" valign="top" align="center"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0" /></a></td><td width="172" valign="top" align="right">14. Middleware and XML</td></tr></table></div><hr align="left" width="515" /><img src="../gifs/navbar.gif" alt="Library Navigation Links" usemap="#library-map" border="0" /><p><font size="-1"><a href="copyrght.htm">Copyright © 2001</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"><area href="../index.htm" coords="1,1,83,102" shape="rect" /><area href="../lnut/index.htm" coords="81,0,152,95" shape="rect" /><area href="../run/index.htm" coords="172,2,252,105" shape="rect" /><area href="../apache/index.htm" coords="238,2,334,95" shape="rect" /><area href="../sql/index.htm" coords="336,0,412,104" shape="rect" /><area href="../dbi/index.htm" coords="415,0,507,101" shape="rect" /><area href="../cgi/index.htm" coords="511,0,601,99" shape="rect" /></map></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -