Hi Frank,<br><br>Ok, I agree with you that the MapServer doc says that the getBytes() function "Returns the image contents as a binary buffer". And I see in tiff_read.py that tiff_vsimem() function is supposed to "# Test reading a tiff from a memory buffer (#2931)", but there must be a difference between the binary buffer that MS returns, and the memory buffer that tiff_vsimem is reading as input.<br>
<br>I implemented your recommendation in the code below, and I am getting an error when I try to open the buffer as it is done in the tiff_read code, "TypeError: fileio() argument 1 must be encoded string without NULL bytes, not str"<br>
<br>#! /usr/bin/python<br><br>from mapscript import mapObj<br>from osgeo import gdal<br><br>def getImageData():<br> mapobject = mapObj('basemap.map')<br> mapimage = mapobject.draw()<br> image_data = mapimage.getBytes()<br>
return image_data<br><br>def cropImage(image_data):<br> open(image_data, mode='rb').read()<br><br>def main():<br> image_data = getImageData()<br> cropImage(image_data)<br><br><br>if __name__ == "__main__":<br>
main()<br><br>I'm trying to figure out how to manipulate the getBytes() buffer in such a way that "open" will work on it, but so far am not having any luck.<br><br>Roger<br>--<br><br><br><br><div class="gmail_quote">
On Sat, Jan 16, 2010 at 5:57 PM, Frank Warmerdam <span dir="ltr"><<a href="mailto:warmerdam@pobox.com">warmerdam@pobox.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Roger André wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi Frank,<br>
<br><div class="im">
Ok, that makes sense. So for this to work, I will have to know (somehow) what type of image mapserver is sending, and then instantiate a MEM dataset with the correct parameters. Problem with that is that I can't think of a good way to read what those parameters are out of the binary string. It's no problem when I know exactly what data is coming in, as is the case for my very specific need, but it means that swapping in GDAL for PIL as a general solution might not be possible.<br>
</div></blockquote>
<br>
Roger,<br>
<br>
I was confused about what you were using before, and now I realize you<br>
are calling imageObj.getBytes() in mapscript (as you did explain!).<br>
<br>
Reading the docs for this function:<br>
/*<br>
-------------------------------------------------------------------------<br>
getBytes returns a gdBuffer structure (defined in mapscript.i) which must<br>
be typemapped to an object appropriate to the target language. This<br>
typemap must also gdFree the data member of the gdBuffer. See the type-<br>
maps in java/javamodule.i and python/pymodule.i for examples.<br>
<br>
contributed by Jerry Pisk, <a href="mailto:jerry.pisk@gmail.com" target="_blank">jerry.pisk@gmail.com</a><br>
-------------------------------------------------------------------------<br>
*/<br>
<br>
it seems it may be difficult to do alot with the result. Hmm, in fact<br>
looking at the code:<br>
<br>
gdBuffer getBytes()<br>
{<br>
gdBuffer buffer;<br>
<br>
buffer.owns_data = MS_TRUE;<br>
<br>
buffer.data = msSaveImageBuffer(self, &buffer.size, self->format);<br>
<br>
if( buffer.data == NULL || buffer.size == 0 )<br>
{<br>
buffer.data = NULL;<br>
msSetError(MS_MISCERR, "Failed to get image buffer", "getBytes");<br>
return buffer;<br>
}<br>
<br>
return buffer;<br>
}<br>
<br>
it isn't doing what is suggested by the comments. It is actually encoding<br>
it into whatever the format selected was (perhaps jpeg or png) and returning<br>
the raw bytes of that.<br>
<br>
My approach before depended on the image being a raw image (uncompressed,<br>
without any format specific headers). What you need is a way of opening<br>
a supported file format, but from a memory buffer.<br>
<br>
This sequence from autotest/gcore/tiff_read.py gives a clue how this might<br>
be done in the GDAL Python bindings:<br>
<br>
content = open('data/byte.tif', mode='rb').read()<br>
<br>
# Create in-memory file<br>
gdal.FileFromMemBuffer('/vsimem/tiffinmem', content)<br>
<br>
ds = gdal.Open('/vsimem/tiffinmem', gdal.GA_Update)<br>
<br>
You won't need to worry about copying palettes or anything.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
One last question. How does a utility like gdal_translate figure out what the input data type is?<br>
</blockquote>
<br></div>
gdal.Open() reads a small chunk from the beginning of the file, and<br>
then, in sequence, passes this to the Open method of each driver along<br>
with the filename and some other info. Each Open() has to decide if the<br>
referenced file is in it's format by whatever mechanism is appropriate.<br>
Usually this is done by looking for "magic" bytes for that format at<br>
the beginning of the file.<div><div></div><div class="h5"><br>
<br>
Best regards,<br>
-- <br>
---------------------------------------+--------------------------------------<br>
I set the clouds in motion - turn up | Frank Warmerdam, <a href="mailto:warmerdam@pobox.com" target="_blank">warmerdam@pobox.com</a><br>
light and sound - activate the windows | <a href="http://pobox.com/%7Ewarmerdam" target="_blank">http://pobox.com/~warmerdam</a><br>
and watch the world go round - Rush | Geospatial Programmer for Rent<br>
<br>
</div></div></blockquote></div><br>