std.algorithm for images

Adam D. Ruppe destructionator at gmail.com
Sun Apr 10 21:12:01 PDT 2011


I spent a little more time on it and implemented simple PNG writing
from the lines range and fixed a few bugs.

What I really want to see with the ranges is things like using
std.algorithm to make an image diff in just a few lines, and also
being able to use image functions as generic algorithms; they should
be fairly interchangeable.

While that's still a long way off (if we'll ever get there), the
range approach can do some pretty cool things. Check this out:

(first get the new file: http://arsdnet.net/dcode/imagedraft.d )

===

import imagedraft;
import std.stdio;
import std.random;

// Why the hell isn't something like this in Phobos?
struct BinaryFileWriter {
	File f;
	this(string filename) {
		f = File(filename, "wb");
	}

	void put(in ubyte[] data) {
		f.rawWrite(data);
	}
}

// This is a little range to create an image on the fly
struct StaticGenerator {
	int width;
	int height;
	int linesLeft;
	this(int width, int height) {
		this.width = width;
		this.height = height;
		linesLeft = height;
		assert(linesLeft);
	}

	bool empty() {
		return !(linesLeft > 0);
	}

        // required by writePng
	int length() {
		return height;
	}

	void popFront() {
		assert(linesLeft);
		linesLeft--;
	}

	RgbaScanline front() {
		assert(linesLeft);
		RgbaScanline line;
		line.pixels.length = width;
		foreach(ref pixel; line.pixels) {
			ubyte val = cast(ubyte) uniform(0, 255);
			pixel = Color(val, val, val, 255);
		}

		return line;
	}
}

void main(string[] args) {
    // writePng takes an output range and an input range. The
    // output range should accept the ubyte[]s it generates.
    // The input range needs to provide length and it's front
    // should be some RgbaScanlines
    writePng(
        BinaryFileWriter("static.png"),
        StaticGenerator(512, 512));
}

===

Nothing particularly great, yet, but it's slowly becoming something
useful.

I also improved the convertToGreyscale function so the results
don't suck as much, making it a fun little function to play with
too.


========

On a completely unrelated note, I've written basic .wav and fairly
decent .mid file functions too. The .wav can read and write
simple files to an array and add some simple sounds to it (square
wave, etc. I generated my phone's ringtone with a little D program!)
Wav is kinda buggy, but I'm sure if I spent a couple hours on it,
it'd be whipped into shape.

And the .mid functions read them into a series of events, can write
back out, and can also play the files on Windows and Linux*,
including injecting events as they play.

* Linux midi support sucks and requires a lot of code and user
setup... but if you have a working ALSA rig, the program will drive
it.


Just since I'm talking about file formats, if there's any interest,
I can see about cleaning these up too for simple sound support in
the library.


More information about the Digitalmars-d mailing list