The neon processing and relief processing algorithms share the same relationship between pixels and neighboring pixels. Therefore, they are written together.
Neon Processing
About the effect of the neon lights, you can look at the Baidu picture.
Neon processing algorithm: taking a 3*3 dot matrix as an example, the target pixel g (I, j) should be f (I, j) and F (I, j + 1 ), the gradient of f (I, j) and F (I + 1, J) serves as the R, G, and B components. We may set f (I, j) the RGB components of are (R1, G1, B1), F (I, j + 1) (R2, G2, B2), F (I + 1, J) is (R3, G3, B3), g (I, j) is (R, G, B), then the result should be
R = 2 * SQRT (R1-R2) ^ 2 + (R1-R3) ^ 2)
G = 2 * SQRT (G1-G2) ^ 2 + (G1-G3) ^ 2)
B = 2 * SQRT (B1-B2) ^ 2 + (B1-B3) ^ 2)
F (I, j) = 2 * SQRT [(f (I, j)-f (I + 1, J) ^ 2 + (f (I, j) -F (, J + 1) ^ 2]
/// <Summary>
/// Neon Processing
/// </Summary>
Public class neonimage: iimageprocessable
{
Public void processbitmap (bitmap BMP)
{
Int width = BMP. width;
Int Height = BMP. height;
For (INT I = 0; I <width-1; I ++) // pay attention to boundary control.
{
For (Int J = 0; j {
Color PC3 = BMP. getpixel (I, j );
Color CC2 = BMP. getpixel (I, j + 1 );
Color CC3 = BMP. getpixel (I + 1, J );
Int RR = 2 * (INT) math. SQRT (cc3.r-cc1.r) * (cc3.r-cc1.r) + (cc2.r-cc1.r) * (cc2.r-cc1.r ));
Int Gg = 2 * (INT) math. SQRT (cc3.g-cc1.g) * (cc3.g-cc1.g) + (cc2.g-cc1.g) * (cc2.g-cc1.g ));
Int BB = 2 * (INT) math. SQRT (cc3. B-cc1. B) * (cc3. B-cc1. B) + (cc2. B-cc1. B) * (cc2. B-cc1. B ));
If (RR> 255) RR = 255;
If (Gg> 255) Gg = 255;
If (BB> 255) BB = 255;
BMP. setpixel (I, j, color. fromargb (RR, GG, BB ));
}
}
}
# Region iimageprocessable Member
Public unsafe void unsafeprocessbitmap (bitmap BMP)
{
Int width = BMP. width;
Int Height = BMP. height;
Rectangle rect = new rectangle (0, 0, width, height );
Bitmapdata bmp data = BMP. lockbits (rect, imagelockmode. readwrite, pixelformat. format32bppargb );
Byte * PTR = (byte *) (BMP data. scan0 );
For (INT I = 0; I {
For (Int J = 0; j <width-1; j ++)
{
Byte BB = (byte) (2 * Math. SQRT (PTR [4]-PTR [0]) * (PTR [4]-PTR [0]) + (PTR [BMP data. stride]-PTR [0]) * (PTR [BMP data. stride]-PTR [0]); // B;
Byte Gg = (byte) (2 * Math. SQRT (PTR [5]-PTR [1]) * (PTR [5]-PTR [1]) + (PTR [BMP data. stride + 1]-PTR [1]) * (PTR [BMP data. stride + 1]-PTR [1]); // G
Byte RR = (byte) (2 * Math. SQRT (PTR [6]-PTR [2]) * (PTR [6]-PTR [2]) + (PTR [BMP data. stride + 2]-PTR [2]) * (PTR [BMP data. stride + 2]-PTR [2]); // R
If (RR> 255) RR = 255;
If (Gg> 255) Gg = 255;
If (BB> 255) BB = 255;
PTR [0] = BB;
PTR [1] = GG;
PTR [2] = RR;
PTR + = 4;
}
PTR + = BMP data. stride-width * 4;
}
BMP. unlockbits (BMP data );
}
# Endregion
}
Embossed Processing
Embossed Processing Principle: A constant (usually 128) is added after the pixel value of the image pixel is subtracted from the pixel value of the adjacent pixel, and then used as the value of the new pixel.
/*************************************** *****************************
*
* Embossed Processing Principle: subtract the pixel value of the image pixel from the pixel value of the adjacent pixel, add 128, and then use it as the value of the new Pixel...
* G (I, j) = f (I, I)-f (I + 1, J) + 128
*
**************************************** ***************************/
/// <Summary>
/// Embossed Processing
/// </Summary>
Public class reliefimage: iimageprocessable
{
Public void processbitmap (system. Drawing. bitmap BMP)
{
Int width = BMP. width;
Int Height = BMP. height;
For (INT I = 0; I <width-1; I ++) // note that the Adjacent Elements of the boundary I + 1 = width
{
For (Int J = 0; j {
Color C1 = BMP. getpixel (I, j );
Color C2 = BMP. getpixel (I + 1, J); // adjacent pixels
Int RR = c1.r-c2.r + 128;
Int Gg = c1.g-c2.g + 128;
Int BB = c1. B-c2. B + 128;
// Handle overflow
If (RR> 255) RR = 255;
If (RR <0) RR = 0;
If (Gg> 255) Gg = 255;
If (Gg <0) Gg = 0;
If (BB> 255) BB = 255;
If (BB <0) BB = 0;
BMP. setpixel (I, j, color. fromargb (RR, GG, BB ));
}
}
}
# Region iimageprocessable Member
Public unsafe void unsafeprocessbitmap (bitmap BMP)
{
Int width = BMP. width;
Int Height = BMP. height;
Rectangle rect = new rectangle (0, 0, width, height );
Bitmapdata bmp data = BMP. lockbits (rect, imagelockmode. readwrite, pixelformat. format32bppargb );
Byte * PTR = (byte *) (BMP data. scan0 );
Int RR = 0, GG = 0, BB = 0;
For (INT I = 0; I {
For (Int J = 0; j <width-1; j ++)
{
BB = (PTR [0]-PTR [3] + 128); // B
Gg = (PTR [1]-PTR [5] + 128); // G
RR = (PTR [2]-PTR [6] + 128); // R
// Handle overflow
If (RR> 255) RR = 255;
If (RR <0) RR = 0;
If (Gg> 255) Gg = 255;
If (Gg <0) Gg = 0;
If (BB> 255) BB = 255;
If (BB <0) BB = 0;
PTR [0] = (byte) BB;
PTR [1] = (byte) GG;
PTR [2] = (byte) RR;
PTR + = 4;
}
PTR + = BMP data. stride-width * 4;
}
BMP. unlockbits (BMP data );
}
# Endregion
}
It can be seen from the figure that the relief processing does not make the image "distorted", even though it is processed as a relief, the relief is still very clear. Why is 128 in the formula? You can use another constant to try it. If it is too small, the image is black. If
If the image is too large, the image is white, and the image size is 128.