|
|
@ -264,25 +264,16 @@ namespace ImageProcessor.Imaging |
|
|
{ |
|
|
{ |
|
|
int width = sourceBitmap.Width; |
|
|
int width = sourceBitmap.Width; |
|
|
int height = sourceBitmap.Height; |
|
|
int height = sourceBitmap.Height; |
|
|
|
|
|
Bitmap destinationBitmap = new Bitmap(width, height); |
|
|
|
|
|
|
|
|
BitmapData sourceData = sourceBitmap.LockBits( |
|
|
using (FastBitmap sourceFastBitmap = new FastBitmap(sourceBitmap)) |
|
|
new Rectangle(0, 0, width, height), |
|
|
{ |
|
|
ImageLockMode.ReadOnly, |
|
|
using (FastBitmap destinationFastBitmap = new FastBitmap(destinationBitmap)) |
|
|
PixelFormat.Format32bppArgb); |
|
|
{ |
|
|
|
|
|
|
|
|
int strideWidth = sourceData.Stride; |
|
|
|
|
|
int scanHeight = sourceData.Height; |
|
|
|
|
|
|
|
|
|
|
|
int bufferSize = strideWidth * scanHeight; |
|
|
|
|
|
byte[] pixelBuffer = new byte[bufferSize]; |
|
|
|
|
|
byte[] resultBuffer = new byte[bufferSize]; |
|
|
|
|
|
|
|
|
|
|
|
Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); |
|
|
|
|
|
sourceBitmap.UnlockBits(sourceData); |
|
|
|
|
|
|
|
|
|
|
|
int kernelLength = kernel.GetLength(0); |
|
|
int kernelLength = kernel.GetLength(0); |
|
|
int radius = kernelLength >> 1; |
|
|
int radius = kernelLength >> 1; |
|
|
int kernelSize = kernelLength * kernelLength; |
|
|
int kernelSize = kernelLength * kernelLength; |
|
|
|
|
|
int threshold = this.Threshold; |
|
|
|
|
|
|
|
|
// For each line
|
|
|
// For each line
|
|
|
for (int y = 0; y < height; y++) |
|
|
for (int y = 0; y < height; y++) |
|
|
@ -300,9 +291,6 @@ namespace ImageProcessor.Imaging |
|
|
double green; |
|
|
double green; |
|
|
double red = green = blue = alpha = divider = processedKernelSize = 0; |
|
|
double red = green = blue = alpha = divider = processedKernelSize = 0; |
|
|
|
|
|
|
|
|
// The location of the pixel bytes.
|
|
|
|
|
|
int byteOffset = (y * strideWidth) + (x * 4); |
|
|
|
|
|
|
|
|
|
|
|
// For each kernel row
|
|
|
// For each kernel row
|
|
|
for (int i = 0; i < kernelLength; i++) |
|
|
for (int i = 0; i < kernelLength; i++) |
|
|
{ |
|
|
{ |
|
|
@ -335,19 +323,14 @@ namespace ImageProcessor.Imaging |
|
|
|
|
|
|
|
|
if (offsetX < width) |
|
|
if (offsetX < width) |
|
|
{ |
|
|
{ |
|
|
int calcOffset = (offsetX * 4) + (offsetY * sourceData.Stride); |
|
|
Color color = sourceFastBitmap.GetPixel(offsetX, offsetY); |
|
|
byte sourceBlue = pixelBuffer[calcOffset]; |
|
|
|
|
|
byte sourceGreen = pixelBuffer[calcOffset + 1]; |
|
|
|
|
|
byte sourceRed = pixelBuffer[calcOffset + 2]; |
|
|
|
|
|
byte sourceAlpha = pixelBuffer[calcOffset + 3]; |
|
|
|
|
|
|
|
|
|
|
|
double k = kernel[i, j]; |
|
|
double k = kernel[i, j]; |
|
|
divider += k; |
|
|
divider += k; |
|
|
|
|
|
|
|
|
red += k * sourceRed; |
|
|
red += k * color.R; |
|
|
green += k * sourceGreen; |
|
|
green += k * color.G; |
|
|
blue += k * sourceBlue; |
|
|
blue += k * color.B; |
|
|
alpha += k * sourceAlpha; |
|
|
alpha += k * color.A; |
|
|
|
|
|
|
|
|
processedKernelSize++; |
|
|
processedKernelSize++; |
|
|
} |
|
|
} |
|
|
@ -380,29 +363,18 @@ namespace ImageProcessor.Imaging |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Add any applicable threshold.
|
|
|
// Add any applicable threshold.
|
|
|
red += this.Threshold; |
|
|
red += threshold; |
|
|
green += this.Threshold; |
|
|
green += threshold; |
|
|
blue += this.Threshold; |
|
|
blue += threshold; |
|
|
alpha += this.Threshold; |
|
|
alpha += threshold; |
|
|
|
|
|
|
|
|
resultBuffer[byteOffset] = blue.ToByte(); |
|
|
destinationFastBitmap.SetPixel(x, y, Color.FromArgb(alpha.ToByte(), red.ToByte(), green.ToByte(), blue.ToByte())); |
|
|
resultBuffer[byteOffset + 1] = green.ToByte(); |
|
|
} |
|
|
resultBuffer[byteOffset + 2] = red.ToByte(); |
|
|
} |
|
|
resultBuffer[byteOffset + 3] = alpha.ToByte(); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Bitmap resultBitmap = new Bitmap(width, height); |
|
|
return destinationBitmap; |
|
|
|
|
|
|
|
|
BitmapData resultData = resultBitmap.LockBits( |
|
|
|
|
|
new Rectangle(0, 0, width, height), |
|
|
|
|
|
ImageLockMode.WriteOnly, |
|
|
|
|
|
PixelFormat.Format32bppArgb); |
|
|
|
|
|
|
|
|
|
|
|
Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); |
|
|
|
|
|
resultBitmap.UnlockBits(resultData); |
|
|
|
|
|
|
|
|
|
|
|
return resultBitmap; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#region Private
|
|
|
#region Private
|
|
|
|