📄 adjustment.cs
字号:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// 因为已经是灰度色,
// 这里只取蓝色分量作为灰度进行运算
gray = p[0];
// 伪彩色处理
switch (gray / 64)
{
case 0:
R = 0;
G = 4 * gray;
B = 255;
break;
case 1:
R = 0;
G = 255;
B = 511 - 4 * gray;
break;
case 2:
R = 4 * gray - 511;
G = 255;
B = 0;
break;
case 3:
R = 255;
G = 1023 - 4 * gray;
B = 0;
break;
}
p[0] = (byte)B;
p[1] = (byte)G;
p[2] = (byte)R;
p += BPP;
} // x
p += offset;
} // y
}
b.UnlockBits(data);
return b;
} // end of PseudoColor
/// <summary>
/// 按色彩表形式映射伪彩色
/// </summary>
/// <param name="b">灰度位图流</param>
/// <param name="colorTable">色彩映射表</param>
/// <returns></returns>
public Bitmap PseudoColor(Bitmap b, Color[] colorTable)
{
int width = b.Width;
int height = b.Height;
// 颜色对照表
int lenColorTable = colorTable.Length;
uint[] ColorTable = new uint[lenColorTable];
// 将颜色转换为数字
for (int i = 0; i < lenColorTable; i++)
{
ColorTable[i] = (uint)((colorTable[i].A << 24) |
(colorTable[i].R << 16) |
(colorTable[i].G << 8) |
(colorTable[i].B << 0));
} // i
BitmapData data = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * BPP;
int gray = 0;
uint color = 0;
// 避免在下面的循环中,出现色彩表索引越界
lenColorTable--;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// 因为已经是灰度色,
// 这里只取蓝色分量作为灰度进行运算
gray = p[0];
// 转化灰度级,并映射到色彩表
color = ColorTable[lenColorTable * gray / 255];
p[3] = (byte)(color >> 24); // A
p[2] = (byte)(color >> 16); // R
p[1] = (byte)(color >> 8); // G
p[0] = (byte)(color); // B
p += BPP;
} // x
p += offset;
} // y
}
b.UnlockBits(data);
return b;
} // end of PseudoColor
/************************************************************
*
* 轮换通道、提取通道、过滤通道
*
************************************************************/
/// <summary>
/// 轮换通道
/// </summary>
/// <param name="b">位图流</param>
/// <returns></returns>
public Bitmap RotateChannel(Bitmap b)
{
int width = b.Width;
int height = b.Height;
Bitmap dstImage = (Bitmap)b.Clone();
BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
byte* src = (byte*)srcData.Scan0;
byte* dst = (byte*)dstData.Scan0;
int offset = srcData.Stride - width * BPP;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
dst[2] = src[1]; // R <- G
dst[1] = src[0]; // G <- B
dst[0] = src[2]; // B <- R
src += BPP;
dst += BPP;
} // x
src += offset;
dst += offset;
} // y
}
b.UnlockBits(srcData);
dstImage.UnlockBits(dstData);
b.Dispose();
return dstImage;
} // end of RotateChannel
/// <summary>
/// 通道模式
/// </summary>
public enum ChannelMode : int
{
/// <summary>
/// 蓝色通道
/// </summary>
Blue = 1,
/// <summary>
/// 绿色通道
/// </summary>
Green = 2,
/// <summary>
/// 红色通道
/// </summary>
Red = 4,
/// <summary>
/// Alpha 通道
/// </summary>
Alpha = 8,
/// <summary>
/// 青色 = 绿色 + 蓝色
/// </summary>
Cyan = 3,
/// <summary>
/// 品红 = 红色 + 蓝色
/// </summary>
Megenta = 5,
/// <summary>
/// 黄色 = 红色 + 绿色
/// </summary>
Yellow = 6,
/// <summary>
/// 白色 = 红色 + 绿色 + 蓝色
/// </summary>
White = 7
}
/// <summary>
/// 提取通道
/// </summary>
/// <param name="b">位图流</param>
/// <param name="channelMode">通道模式[A, R, G, B]</param>
/// <returns></returns>
public Bitmap ExtractChannel(Bitmap b, ChannelMode channelMode)
{
int channel = (int)Math.Log((double)channelMode,2.0);
int width = b.Width;
int height = b.Height;
Bitmap dstImage = (Bitmap)b.Clone();
BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
byte* src = (byte*)srcData.Scan0;
byte* dst = (byte*)dstData.Scan0;
int offset = srcData.Stride - width * BPP;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
dst[0] = dst[1] = dst[2] = src[channel];
src += BPP;
dst += BPP;
} // x
src += offset;
dst += offset;
} // y
}
b.UnlockBits(srcData);
dstImage.UnlockBits(dstData);
b.Dispose();
return dstImage;
} // end of ExtractChannel
/// <summary>
/// 过滤通道
/// </summary>
/// <param name="b">位图流</param>
/// <param name="channelMode">通道模式</param>
/// <returns></returns>
public Bitmap FilterChannel(Bitmap b, ChannelMode channelMode)
{
int channel = (int)channelMode;
int width = b.Width;
int height = b.Height;
BitmapData data = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * BPP;
for (int i = 0; i < 3; i++)
{
if (((int)Math.Pow(2, i) & channel) > 0)
continue;
p = (byte*)data.Scan0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
p[i] = 0;
p += BPP;
} // x
p += offset;
} // y
} // i
}
b.UnlockBits(data);
return b;
} // end of FilterChannel
/************************************************************
*
* 映射
*
************************************************************/
/// <summary>
/// 图像色彩映射
/// </summary>
/// <param name="b">位图流</param>
/// <param name="Map">映射表</param>
/// <param name="channelMode">通道模式</param>
/// <returns></returns>
public Bitmap Mapping(Bitmap b, byte[] Map, ChannelMode channelMode)
{
int channel = (int)channelMode;
int width = b.Width;
int height = b.Height;
BitmapData data = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* p = (byte*)data.Scan0;
int offset = data.Stride - width * BPP;
for (int i = 0; i < 3; i++)
{
if (((int)Math.Pow(2, i) & channel) == 0)
continue;
p = (byte*)data.Scan0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
p[i] = Map[p[i]];
p += BPP;
} // x
p += offset;
} // y
} // i
}
b.UnlockBits(data);
return b;
} // end of Mapping
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -