Need help designing a pair of RMagick methods

T

Timothy Hunter

I don't get to write much "real-world" Ruby code so I thought I'd ask
for help from the community. I'd like your advice about the design for
the RMagick[1] bindings for a part of the ImageMagick API that I have
never gotten around to surfacing. I apologize for the length of this
posting but I figure that too much detail is better than too little.

ImageMagick's "stream" API[2] is two C functions, ReadStream and
WriteStream, that are useful for transferring pixel data from very large
images without putting all the pixel data in memory at once. (RMagick
already has Magick::Image#import_pixels[3] and
Magick::Image#export_pixels[4], but these two methods require that all
the pixel data be in memory at once, either in an array or in a string.)
The ReadStream and WriteStream functions transfer pixel data a row (or
portion of a row) at a time. The pixel data are presented as a C array
of binary numbers whose size and order (for example "char" and "RGB")
must be specified by the caller. The stream functions accept a number of
optional arguments similar to the existing Magick::Image.read[5] and
Magick::Image#write[6] methods. Where the pixel data are transferred to
is up to the caller. The ImageMagick stream command[7] always writes the
data to a file.

I have already decided on some parts of the design. The ReadStream
function will be surfaced as read_stream, a singleton method in the
Magick::Image class similar to the read method. Like read, it will
accept either a filename or an open File object that identifies the
input image file, and an "optional arguments" block. It will read the
pixel data from the image file one row at a time and deliver the data to
the "sink" specified by an argument. (Unlike read, this method does not
construct an Image object.)

The WriteStream method will be surfaced as write_stream, an instance
method in the Magick::Image class similar to the write method. Like
write, it will accept an "optional arguments" block. It will take the
pixel data from the image object a row at a time and deliver the data to
the "sink" specified by an argument.

This leaves two (at least) unresolved issues. (1) What is the "sink" and
how do the methods use it? (2) what form should the pixel data be when
passed to the sink?

The obvious (to me, anyway) answers are (1) The sink is an IO object
that has already been opened for binary output. The methods call
IO#write. (2) The pixel data are represented as a plain Ruby string.

Am I overlooking something? Are there kinds of sinks that aren't IO
objects (a proc, for example) and want the pixel data in some other
form, such as an array? If so, what would the method calls look like?
Should there be more than two methods?

Thanks in advance for your help. Whatever happens I'll add these methods
to the next release of RMagick.


[1] http://rmagick.rubyforge.org
[2] http://www.imagemagick.org/api/stream.php
[3] http://www.simplesystems.org/RMagick/doc/image2.html#import_pixels
[4] http://www.simplesystems.org/RMagick/doc/image2.html#export_pixels
[5] http://www.simplesystems.org/RMagick/doc/image1.html#read
[6] http://www.simplesystems.org/RMagick/doc/image3.html#write
[7] http://www.imagemagick.org/script/stream.php
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top