我编写了下面的代码来操纵图像的颜色。我想以某种方式撕开图像的每个像素。因此,对于每个像素,我想要访问5位红色,6位绿色和5位蓝色(根据16位图像)。我如何更改我的代码来执行此操作?我想我必须以某种方式将我设置的字节值转换为位?
任何帮助都会很棒。
private Bitmap InvertBitmap(Bitmap bmp)
{
unsafe
{
//create an empty bitmap the same size as original
Bitmap newBitmap = new Bitmap(bmp.Width, bmp.Height);
//lock the original bitmap in memory
System.Drawing.Imaging.BitmapData originalData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//lock the new bitmap in memory
System.Drawing.Imaging.BitmapData newData = newBitmap.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//set the number of bytes per pixel
int pixelSize = 3;
for (int y = 0; y < bmp.Height; y++)
{
//get the data from the original image
byte* originalImageRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
//get the data from the new image
byte* newImageRow = (byte*)newData.Scan0 + (y * newData.Stride);
for (int x = 0; x < bmp.Width; x++)
{
//set the new image's pixel to the inverted version
newImageRow[x * pixelSize] = (byte)(255 - originalImageRow[x * pixelSize + 0]); //B
newImageRow[x * pixelSize + 1] = (byte)(255 - originalImageRow[x * pixelSize + 1]); //G
newImageRow[x * pixelSize + 2] = (byte)(255 - originalImageRow[x * pixelSize + 2]); //R
}
}
//unlock the bitmaps
newBitmap.UnlockBits(newData);
bmp.UnlockBits(originalData);
return newBitmap;
}
}
答案 0 :(得分:2)
如果你有一个16位整数x,你可以先用二进制AND屏蔽这些位,然后移动结果,从而提取其中的位范围。像这样:
int x = 33808; // 1000010000010000, for testing
int r = (x & 63488) >> 11; // 63488 = 1111100000000000
int g = (x & 2016) >> 5; // 2016 = 0000011111100000
int b = (x & 31); // 31 = 0000000000011111
// r = 10000
// g = 100000
// b = 10000
我希望有所帮助。
答案 1 :(得分:1)
RGB24每个颜色通道为1个字节,因此您无需进行任何操作即可从已有数据中提取它们。 “获取位”并没有真正意义,因为你可以设置它们的值,例如。
newImageRow[x * pixelSize] = (byte)(originalImageRow[x * pixelSize + 0] | 0x80); //B
将新图像蓝色通道设置为原始图像蓝色通道,但会将高位设置为1.
newImageRow[x * pixelSize] = (byte)(originalImageRow[x * pixelSize + 0] ^ 0xFF); //B
会反转频道。
所以你真的需要对你已经拥有的数据使用按位运算符(|&amp;&gt;&gt;&lt;&lt; ^)。