I've spent a fair amount of time developing computer-generated fractal art (link and link). For example, this is one of my Newton fractals (which is derived from the time it takes for Newton's method to converge to a zero from various starting locations in the complex plane given a specified polynomial):
The Eye |
A naive method to setting every pixel in the Bitmap is:
public static Bitmap drawNaive(Color[,] data) { int height = data.GetLength(0); int width = data.GetLength(1); Bitmap result = new Bitmap(width, height); for(int row = 0; row < height; row++) { for(int col = 0; col < width; col++) { Color color = data[row, col]; //Set the pixel using the exposed method by the // Bitmap class (slow!) result.SetPixel(col, row, color); } } return result; }
However, this solution is relatively slow because it requires an expensive operation to lock and unlock the bitmap every time a pixel is set. Must better performance can be had by using pointers (which is permitted when "unsafe" code is used). Bitmaps are very simple objects that hold the intensity of Red, Green, Blue and the Alpha (transparency) channel at each pixel in four bytes (1 byte each) from the top-left corner, across each row, and then down the image to the bottom right corner. Our strategy will be:
- Declare a struct representing a pixel
- Lock the bitmap once at the start
- Use pointers to scan through the image, updating pixels
- Unlock the bitmap once at the end
public struct PixelData { public byte B; public byte G; public byte R; public byte A; public PixelData(byte r, byte g, byte b, byte a) { this.R = r; this.G = g; this.B = b; this.A = a; } }
This can be used then to sweep along the Bitmap.
public static Bitmap drawPointer(Color[,] data) { int height = data.GetLength(0); int width = data.GetLength(1); Bitmap result = new Bitmap(width, height); //Lock the entire bitmap (the rectangle argument) once BitmapData locked = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); //Enter unsafe mode so that we can use pointers unsafe { //Get a pointer to the beginning of the pixel data region //The upper-left corner PixelData* pixelPtr = (PixelData*)(void*)locked.Scan0; //Iterate through rows and columns for(int row = 0; row < height; row++) { for(int col = 0; col < width; col++) { Color color = data[row, col]; //Set the pixel (fast!) *pixelPtr = new PixelData(color.R, color.G, color.B, color.A); //Update the pointer pixelPtr++; } } } //Unlock the bitmp result.UnlockBits(locked); return result; }
This results in a significant speed-up.
Is there pointer in C# like C or C++ ?
ReplyDeleteLing
The dealers themselves are fast, environment friendly, and friendly, working tables that start with a $5 minimal buy-in and 카지노사이트 go all greatest way|the method in which} up to as} $5000 all-star sittings with massive payouts. Though Ignition Casino accepts Bitcoin and bank cards, there are several of} reasons to make use of Bitcoin. Bitcoin funds are processed without fees; however, credit card depositors pay 5.9%. Deposit with Bitcoin and use the bonus code IGBITCOIN200 to assert is $2,000 Bitcoin bonus. Virgin Casino was among the many first manufacturers to enter the US market.
ReplyDelete