You are on a tear with this image stuff :)<div><br></div><div>Have you considered wrapping something like DevIL? <a href="http://openil.sourceforge.net/features.php">http://openil.sourceforge.net/features.php</a>  Probably has all the features you could ever want and is cross-platform.</div>
<div><a href="http://openil.sourceforge.net/features.php"></a><br>- Cliff</div><div><br><div class="gmail_quote">On Sun, Apr 10, 2011 at 5:10 PM, Adam D. Ruppe <span dir="ltr"><<a href="mailto:destructionator@gmail.com">destructionator@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I'm pretty happy with how simpledisplay.d is turning out, and want to<br>
spend some time thinking about the client side images now.<br>
<br>
I think a nice way to do it would be to go with ranges and templates,<br>
like std.algorithm, so things will work across many different image<br>
formats with the best efficiency and minimal coupling. But, we need to<br>
think about some specifics before going too far.<br>
<br>
Here's a first draft module to show the idea while doing some useful<br>
work. It's dependency free so you can download and play with ease.<br>
<br>
<a href="http://arsdnet.net/dcode/imagedraft.d" target="_blank">http://arsdnet.net/dcode/imagedraft.d</a><br>
<br>
<br>
If you also grab simpledisplay.d<br>
<a href="http://arsdnet.net/dcode/simpledisplay.d" target="_blank">http://arsdnet.net/dcode/simpledisplay.d</a><br>
<br>
You can compile this little png display program:<br>
<br>
=======<br>
import imagedraft;<br>
import std.stdio;<br>
<br>
import simpledisplay;<br>
<br>
void main(string[] args) {<br>
        auto png = pngFromBytes(File(args[1]).byChunk(4096));<br>
        auto image = new Image(png.header.width, png.header.height);<br>
<br>
        int y;<br>
        foreach(line; png.byRgbaScanline) {<br>
                foreach(x, color; line.pixels)<br>
                        image.putPixel(cast(int) x, cast(int) y,<br>
                                simpledisplay.Color(color.r, color.g, color.b, color.a));<br>
                y++;<br>
        }<br>
<br>
        displayImage(image);<br>
}<br>
====<br>
<br>
And use it as a base to play around and see your algorithm's results<br>
right in the window. (btw, that displayImage() function is what used<br>
to be image.display() in simpledisplay. A standalone function will<br>
let me separate dependencies better. It works the same way - just<br>
show it and wait for the user to hit any key to continue.)<br>
<br>
The foreach there is ugly. I was going to write up a demo<br>
of some actual algorithms for images, but I ended up spending<br>
most the day getting my BufferedInputRange and LazyPngFile to<br>
work correctly...<br>
<br>
But, you can see one of the big ideas: providing ranges on images<br>
of various formats that present the data to you in a requested<br>
standard format (any PNG image is lazily converted to an rgba list<br>
of lines here).<br>
<br>
It also shows how I plan to write other image format loaders - they<br>
take arbitrary input ranges, and lazily load and decode the file.<br>
(While I had a png loader before, it was in C style.... I'm hoping<br>
that it will be easier to port my bmp code now that I have a working<br>
foundation...)<br>
<br>
I'll write an image saver too. It will take an rgbaScanLine range<br>
and save it to the correct format - png, bmp, whatever.<br>
<br>
<br>
Now, back to the main idea here. I wish I had more time. If I fleshed<br>
out this existing range a little more, we could do fun things<br>
like call std.algorithm.levenshteinDistance on it.. but right now,<br>
it's just an input range, which is fairly limited. I figure the<br>
best thing to do is offer whatever facilities the source range offers,<br>
so if you give it an array, you can save(), back(), etc. too.<br>
<br>
Still, we can run a few functions on it.<br>
<br>
 foreach(line; filter!"a.pixels[0].r > 200"(png.byRgbaScanline)) {<br>
 }<br>
<br>
Only keeps lines with a lot of red in the first pixel.<br>
<br>
So that's pretty cool.<br>
<br>
<br>
<br>
Aaaanyway, I want to have a bunch of algorithms written in here that<br>
can work on these ranges, capable of doing both in-place and lazy<br>
changes to your image.<br>
<br>
Since I messed up the time, I only wrote one (and it sucks, hard),<br>
but it's the idea I have in mind: the convertToGreyscale function.<br>
Any image that provides a range it can use will work for it.<br>
<br>
<br>
<br>
What kind of ranges would be useful? A by line surely is, which<br>
is why I started with it. A byPixel perhaps? Maybe a byBlock? Though,<br>
it for byPixel, it seems like opApply is the way to do it. Maybe it<br>
can even shove it off to the GPU to do the work. That's beyond my<br>
knowledge, but David Simcha has done some cool stuff with foreach<br>
and parallelism, and this is basically the same concept, so I'm<br>
sure it can be done.<br>
<br>
Then, of course, you'll surely still want opIndex into the pixels<br>
too.<br>
<br>
I was hoping to have time to write a gaussian blur function to put<br>
the idea to the test...<br>
<br>
<br>
The other thing is drawing. I don't think ranges will help much there.<br>
Drawing algorithms will probably be ok with opIndexAssign into the<br>
pixels.<br>
<br>
<br>
But, it's time for me to get to the work I was supposed to do today.<br>
If nothing else, hopefully that PNG loader in there will be useful,<br>
but I really do think there's a lot of potential in the idea of<br>
a std.algorithm for images and would like any input you have.<br>
<br>
Thanks for all the feedback this weekend, everyone!<br>
</blockquote></div><br></div>