[Mapserver-users] sending image with mod_perl (conclusion)
Jason Thaxter
thaxter at gomoos.org
Fri Mar 7 09:18:52 PST 2003
--QTprm0S8XgL7H0Dt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
A quick re-summary of the issue: under mod_perl, stdout does not go to the
browser/client, it goes to wherever Apache thinks stdout is for itself. So
$img->saveImage(undef,
doesn't really work, though it may sometimes accidentally work, depending on
buffering issues.
So the solution is:
1) extend mapserver code to add a "writeImage" function that takes a
filehandle instead of a file name.
2) extend the Perl interface through SWIG so perl can give the map object
a filehandle to write the image on
3) in perl code, get a filehandle to the browser/client and pass it to the
writeImage function.
Attached you will find a patch against 3.6.4 for parts 1 and 2, and a very
minimal example in perl of how to accomplish part 3. Maybe the execution
could be better, and GD-like behavior (e.g. "print $img->png"), would be more
elegant for the user, but this works now.
Hope this helps. I'll copy this to the dev list later...
Cheers,
Jason
--
----------------------------------------------
Jason Thaxter
GoMOOS, P.O. Box 4919, Portland, ME 04112-4919
Office Location: 1 Canal Plaza, 7th Floor
Office: 207.773.0423
Fax: 207.773.8672
Email: thaxter at gomoos.org
------------www.gomoos.org--------------------
--QTprm0S8XgL7H0Dt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mod_perl_example.cgi"
#!/usr/bin/perl
use strict;
# Map Server
use mapscript;
use XBase;
my $map = new mapscript::mapObj('/home/moxie/tmp/test.map');
my $img = $map->draw();
my $ref_img = $map->drawReferenceMap();
use Time::HiRes 'time';
my $start = time;
# these are for getting the filehandle
use Apache();
use IO::Handle;
my $fh; # this is the filehandle we'll pass to writeImage
if ($ENV{MOD_PERL}){
$fh = IO::Handle->new_from_fd(Apache->request->connection->fileno(1),'w');
}
else {
$fh = \*STDOUT;
}
use CGI ':cgi';
print $fh header( # note the use of the filehandle here...
-type => 'image/png',
);
$ref_img->writeImage($fh, $mapscript::MS_PNG, $map->{transparent}, $map->{interlace},0);
$img->free();
$ref_img->free();
--QTprm0S8XgL7H0Dt
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mod_perl_fixes.diff"
Index: map.h
===================================================================
RCS file: /data2/cvsroot/mapserver/map.h,v
retrieving revision 1.150.2.12
diff -b -u -r1.150.2.12 map.h
--- map.h 8 Jan 2003 19:06:59 -0000 1.150.2.12
+++ map.h 7 Mar 2003 16:53:28 -0000
@@ -729,6 +729,7 @@
// Function prototypes, wrapable
int msSaveImage(gdImagePtr img, char *filename, int type, int transparent, int interlace, int quality);
+int msWriteImage(gdImagePtr img, FILE *stream, int type, int transparent, int interlace, int quality);
void msFreeImage(gdImagePtr img);
// Function prototypes, not wrapable
Index: maputil.c
===================================================================
RCS file: /data2/cvsroot/mapserver/maputil.c,v
retrieving revision 1.108
diff -b -u -r1.108 maputil.c
--- maputil.c 9 Apr 2002 04:55:13 -0000 1.108
+++ maputil.c 7 Mar 2003 16:53:29 -0000
@@ -1183,6 +1183,59 @@
return(MS_SUCCESS);
}
+/*
+** Write an image to a file handle
+*/
+int msWriteImage(gdImagePtr img, FILE *stream , int type, int transparent, int interlace, int quality)
+{
+
+ if(interlace)
+ gdImageInterlace(img, 1);
+
+ if(transparent)
+ gdImageColorTransparent(img, 0);
+
+ switch(type) {
+ case(MS_GIF):
+#ifdef USE_GD_GIF
+ gdImageGif(img, stream);
+#else
+ msSetError(MS_MISCERR, "GIF output is not available.", "msWriteImage()");
+ return(MS_FAILURE);
+#endif
+ break;
+ case(MS_PNG):
+#ifdef USE_GD_PNG
+ gdImagePng(img, stream);
+#else
+ msSetError(MS_MISCERR, "PNG output is not available.", "msWriteImage()");
+ return(MS_FAILURE);
+#endif
+ break;
+ case(MS_JPEG):
+#ifdef USE_GD_JPEG
+ gdImageJpeg(img, stream, quality);
+#else
+ msSetError(MS_MISCERR, "JPEG output is not available.", "msWriteImage()");
+ return(MS_FAILURE);
+#endif
+ break;
+ case(MS_WBMP):
+#ifdef USE_GD_WBMP
+ gdImageWBMP(img, 1, stream);
+#else
+ msSetError(MS_MISCERR, "WBMP output is not available.", "msWriteImage()");
+ return(MS_FAILURE);
+#endif
+ break;
+ default:
+ msSetError(MS_MISCERR, "Unknown output image type.", "msWriteImage()");
+ return(MS_FAILURE);
+ }
+
+ return(MS_SUCCESS);
+}
+
void msFreeImage(gdImagePtr img)
{
gdImageDestroy(img);
Index: mapscript/mapscript.i
===================================================================
RCS file: /data2/cvsroot/mapserver/mapscript/mapscript.i,v
retrieving revision 1.66.2.1
diff -b -u -r1.66.2.1 mapscript.i
--- mapscript/mapscript.i 8 Jul 2002 17:28:16 -0000 1.66.2.1
+++ mapscript/mapscript.i 7 Mar 2003 16:53:30 -0000
@@ -989,6 +989,15 @@
msSaveImage(self->bytes, filename, type, transparent, interlace, quality);
}
+ /* Make FILE * work */
+ %typemap(perl5,in) FILE * {
+ /* $target = IoIFP(sv_2io($source)); older swig */
+ $1 = IoIFP(sv_2io($input));
+ }
+ void writeImage(FILE *stream, int type, int transparent, int interlace, int quality) {
+ msWriteImage(self->bytes, stream, type, transparent, interlace, quality);
+ }
+
}
--QTprm0S8XgL7H0Dt--
More information about the MapServer-users
mailing list