diff options
| author | Mike Wey | 2011-08-07 18:50:40 +0200 |
|---|---|---|
| committer | Mike Wey | 2011-08-07 18:50:40 +0200 |
| commit | 7a9174cc012e93fb0a4d15ef3dcf64f3695b829e (patch) | |
| tree | c3a47e982b02cca9ac9356974da625ec56eea72c | |
| parent | c7be75cbe983021f41f63a95ad07f422b6f34845 (diff) | |
Document the ImageView.
| -rw-r--r-- | dmagick/Image.d | 10 | ||||
| -rw-r--r-- | dmagick/ImageView.d | 182 |
2 files changed, 178 insertions, 14 deletions
diff --git a/dmagick/Image.d b/dmagick/Image.d index 9a10364..7c422fc 100644 --- a/dmagick/Image.d +++ b/dmagick/Image.d @@ -2898,7 +2898,14 @@ class Image imageRef = ImageRef(image); } - dmagick.ImageView.ImageView view(Geometry area) + /** + * Get a view into the image. The ImageView can be used to modify + * individual pixels of the image. + * + * Params: + * area = The area accessible through the view. + */ + dmagick.ImageView.ImageView view(Geometry area = Geometry(cast(size_t)this.columns, cast(size_t)this.rows) ) { return new dmagick.ImageView.ImageView(this, area); } @@ -4053,3 +4060,4 @@ version (Windows) MagickCoreTerminus(); } } + diff --git a/dmagick/ImageView.d b/dmagick/ImageView.d index e5411a4..c5dcf1a 100644 --- a/dmagick/ImageView.d +++ b/dmagick/ImageView.d @@ -1,4 +1,10 @@ -module dmagick.ImageView; +/** + * Copyright: Mike Wey 2011 + * License: zlib (See accompanying LICENSE file) + * Authors: Mike Wey + */ + + module dmagick.ImageView; import std.array; import std.parallelism; @@ -15,11 +21,43 @@ import dmagick.c.cache; import dmagick.c.geometry; import dmagick.c.pixel; +/** + * The ImageView allows changing induvidual pixels with the slicing and + * indexing operators. + * + * -------------------- + * ImageView view = image.view(); + * + * //Assign a square. + * view[4..40][5..50] = new Color("red"); + * + * //Reduce a view. + * view = view[10..view.extend.height-10][20..view.extend.width-20]; + * + * //Assign a single row. + * view[30] = new Color("blue"); + * //Or a column. + * view[][30] = new Color("blue"); + * //And induvidual pixels. + * view[3][5] = new Color("green"); + * + * //We can also use foreach. + * foreach ( row; view ) + * { + * //This is executed in parallel. + * foreach ( ref pixel; row ) + * pixel = new Color("black"); + * } + * -------------------- + */ class ImageView { Image image; RectangleInfo extent; + /** + * Create a new view for image. + */ this(Image image, Geometry area) { if ( area.width + area.xOffset > image.columns || @@ -32,6 +70,36 @@ class ImageView this.extent = area.rectangleInfo; } + /** + * The width of the view. + */ + @property size_t width() const + { + return extent.width; + } + + /** + * The height of the view. + */ + @property size_t height() const + { + return extent.height; + } + + /** + * The height or the width of the view, depending on in which slice + * it's used. + * + * Bugs: dmd bug 3474: opDollar isn't implemented. + */ + size_t opDollar() const + { + return extent.height; + } + + /** + * Indexing operators yield or modify the value at a specified index. + */ Row opIndex(size_t row) { PixelPacket* pixels = @@ -40,11 +108,21 @@ class ImageView return Row(image, pixels[0 .. extent.width]); } + ///ditto + void opIndexAssign(Color color, size_t index) + { + this[index][] = color; + } + + /** + * Sliceing operators yield or modify the value in the specified slice. + */ ImageView opSlice() { return opSlice(0, extent.height); } + ///ditto ImageView opSlice(size_t upper, size_t lower) { RectangleInfo newExtent = extent; @@ -55,6 +133,25 @@ class ImageView return new Rows(image, Geometry(newExtent)); } + ///ditto + void opSliceAssign(Color color) + { + foreach ( row; this ) + row[] = color; + } + + ///ditto + void opSliceAssign(Color color, size_t upper, size_t lower) + { + foreach ( row; this[upper .. lower] ) + row[] = color; + } + + /** + * Support the usage of foreach to loop over the rows in the view. + * The foreach is executed in parallel. + */ + //TODO: Should the foreach be parallel? int opApply(int delegate(ref Row) dg) { shared(int) progress; @@ -82,6 +179,11 @@ class ImageView } } + +/* + * A Rows object is returned when a ImageView is sliced, this is to support + * sliceing the columns with a sceond slice. + */ class Rows : ImageView { this(Image image, Geometry area) @@ -89,6 +191,20 @@ class Rows : ImageView super(image, area); } + /* + * The height or the width of the view, depending on in which slice + * it's used. + * + * Bugs: dmd bug 3474: opDollar isn't implemented. + */ + override size_t opDollar() const + { + return extent.width; + } + + /* + * Indexing operators yield or modify the value at a specified index. + */ override Row opIndex(size_t column) { PixelPacket* pixels = @@ -97,11 +213,15 @@ class Rows : ImageView return Row(image, pixels[0 .. extent.width]); } + /* + * Sliceing operators yield or modify the value in the specified slice. + */ override ImageView opSlice() { return opSlice(0, extent.width); } + ///ditto override ImageView opSlice(size_t left, size_t right) { RectangleInfo newExtent = extent; @@ -113,6 +233,11 @@ class Rows : ImageView } } +/** + * Row reprecents a singe row of pixels in an ImageView. + * + * Bugs: Only one row per thread is supported. + */ struct Row { Image image; @@ -129,49 +254,80 @@ struct Row SyncAuthenticPixels(image.imageRef, DMagickExceptionInfo()); } + /** + * The number of pixels in this row / column. + * + * Bugs: dmd bug 3474: opDollar isn't implemented. + */ + @property size_t length() const + { + return pixels.length; + } + + ///ditto + size_t opDollar() const + { + return pixels.length; + } + + /** + * Indexing operators yield or modify the value at a specified index. + */ Color opIndex(size_t pixel) { return new Color(&(pixels[pixel])); } - void opIndexAssign(Color color, size_t i) + ///ditto + void opIndexAssign(Color color, size_t index) { - pixels[i] = color.pixelPacket; + pixels[index] = color.pixelPacket; } + /** + * Sliceing operators yield or modify the value in the specified slice. + */ Row opSlice() { return this; } + ///ditto Row opSilce(size_t left, size_t right) { return Row(image, pixels[left .. right]); } + ///ditto void opSliceAssign(Color color) { opSliceAssign(color, 0, pixels.length); } + ///ditto void opSliceAssign(Color color, size_t left, size_t right) { foreach( i; left .. right ) this[i] = color; } - @property bool empty() + /** + * Support using foreach on a row. + */ + int opApply(int delegate(ref Color) dg) { - return pixels.empty; - } + foreach ( ref PixelPacket pixel; pixels ) + { + Color color = new Color(pixel); + int result = dg(color); - Color front() - { - return this[0]; - } + pixel = color.pixelPacket; - void popFront() - { - pixels.popFront(); + if ( result ) + return result; + } + + return 0; } } + |
