// Use the minimum brightness value in a region. public Bitmap32 RankMinimum(int rank, bool lock_result) { // Make a copy of this Bitmap32. Bitmap32 result = this.Clone(); // Lock both bitmaps. bool was_locked = this.IsLocked; this.LockBitmap(); result.LockBitmap(); // Calculate bounds to iterate over. int start_i = -rank / 2; int stop_i = rank + start_i; for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { // Find the brightest pixel around this one. int best_brightness = GetRed(x, y) + GetGreen(x, y) + GetBlue(x, y); int best_row = y; int best_col = x; for (int dy = start_i; dy < stop_i; dy++) { int row = y + dy; if ((row >= 0) && (row < Height)) { for (int dx = start_i; dx < stop_i; dx++) { int col = x + dx; if ((col >= 0) && (col < Width)) { int test_brightness = GetRed(col, row) + GetGreen(col, row) + GetBlue(col, row); if (test_brightness < best_brightness) { best_brightness = test_brightness; best_row = row; best_col = col; } } } } } // Set this pixel to the brighest value we found. result.SetPixel(x, y, GetRed(best_col, best_row), GetGreen(best_col, best_row), GetBlue(best_col, best_row), 255); } } // Unlock the bitmaps. if (!lock_result) { result.UnlockBitmap(); } if (!was_locked) { this.UnlockBitmap(); } // Return the result. return(result); }
// Apply a filter to the image. public Bitmap32 ApplyFilter(Filter filter, bool lock_result) { // Make a copy of this Bitmap32. Bitmap32 result = this.Clone(); // Lock both bitmaps. bool was_locked = this.IsLocked; this.LockBitmap(); result.LockBitmap(); // Apply the filter. int xoffset = -(int)(filter.Kernel.GetUpperBound(1) / 2); int yoffset = -(int)(filter.Kernel.GetUpperBound(0) / 2); int xmin = -xoffset; int xmax = Bitmap.Width - filter.Kernel.GetUpperBound(1); int ymin = -yoffset; int ymax = Bitmap.Height - filter.Kernel.GetUpperBound(0); int row_max = filter.Kernel.GetUpperBound(0); int col_max = filter.Kernel.GetUpperBound(1); for (int x = xmin; x <= xmax; x++) { for (int y = ymin; y <= ymax; y++) { // Skip the pixel if any under the kernel // is completely transparent. bool skip_pixel = false; // Apply the filter to pixel (x, y). float red = 0, green = 0, blue = 0; for (int row = 0; row <= row_max; row++) { for (int col = 0; col <= col_max; col++) { int ix = x + col + xoffset; int iy = y + row + yoffset; byte new_red, new_green, new_blue, new_alpha; this.GetPixel(ix, iy, out new_red, out new_green, out new_blue, out new_alpha); // See if we should skip this pixel. if (new_alpha == 0) { skip_pixel = true; break; } red += new_red * filter.Kernel[row, col]; green += new_green * filter.Kernel[row, col]; blue += new_blue * filter.Kernel[row, col]; } if (skip_pixel) { break; } } if (!skip_pixel) { // Divide by the weight, add the offset, and // make sure the result is between 0 and 255. red = filter.Offset + red / filter.Weight; if (red < 0) { red = 0; } if (red > 255) { red = 255; } green = filter.Offset + green / filter.Weight; if (green < 0) { green = 0; } if (green > 255) { green = 255; } blue = filter.Offset + blue / filter.Weight; if (blue < 0) { blue = 0; } if (blue > 255) { blue = 255; } // Set the new pixel's value. result.SetPixel(x, y, (byte)red, (byte)green, (byte)blue, this.GetAlpha(x, y)); } } } // Unlock the bitmaps. if (!lock_result) { result.UnlockBitmap(); } if (!was_locked) { this.UnlockBitmap(); } // Return the result. return(result); }