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;
}
// A standard embossing filter.
public static Filter EmbossingFilter
{
get
{
return new Filter()
{
Weight = 1,
Offset = 127,
Kernel = new float[,]
{
{-1, 0, 0},
{0, 0, 0},
{0, 0, 1},
}
};
}
}
// Apply a filter.
private void ApplyFilter(Bitmap32.Filter filter)
{
Bitmap bm = new Bitmap(picVisible.Image);
this.Cursor = Cursors.WaitCursor;
DateTime start_time = DateTime.Now;
// Make a Bitmap24 object.
Bitmap32 bm32 = new Bitmap32(bm);
// Apply the filter.
Bitmap32 new_bm32 = bm32.ApplyFilter(filter, false);
// Display the result.
picVisible.Image = new_bm32.Bitmap;
DateTime stop_time = DateTime.Now;
this.Cursor = Cursors.Default;
TimeSpan elapsed_time = stop_time - start_time;
lblElapsed.Text = elapsed_time.TotalSeconds.ToString("0.000000");
}
{
// 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;
}
// A standard embossing filter.
public static Filter EmbossingFilter
{
get
{
return new Filter()
{
Weight = 1,
Offset = 127,
Kernel = new float[,]
{
{-1, 0, 0},
{0, 0, 0},
{0, 0, 1},
}
};
}
}
// Apply a filter.
private void ApplyFilter(Bitmap32.Filter filter)
{
Bitmap bm = new Bitmap(picVisible.Image);
this.Cursor = Cursors.WaitCursor;
DateTime start_time = DateTime.Now;
// Make a Bitmap24 object.
Bitmap32 bm32 = new Bitmap32(bm);
// Apply the filter.
Bitmap32 new_bm32 = bm32.ApplyFilter(filter, false);
// Display the result.
picVisible.Image = new_bm32.Bitmap;
DateTime stop_time = DateTime.Now;
this.Cursor = Cursors.Default;
TimeSpan elapsed_time = stop_time - start_time;
lblElapsed.Text = elapsed_time.TotalSeconds.ToString("0.000000");
}
No comments:
Post a Comment