c# - BMP 中的字节到位得到 RGB

标签 c# .net winforms bitmap rgb

我编写了下面的代码来操纵图像的颜色。我想以某种方式撕裂图像的每个像素。因此,对于每个像素,我想要访问 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;
        }
}

最佳答案

如果您有一个 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

希望对您有所帮助。

关于c# - BMP 中的字节到位得到 RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9746130/

相关文章:

c# - 模拟错误域中的用户不会抛出异常

C# WinForms ErrorProvider 控件

c# - 用于粗体和/或斜体的 RichTextBox 字体样式按钮(如何编码以便可以选择多个而不是替换

c# - 正则表达式 - 如何制作前瞻模式

c# - 使用泛型类型 'System.Collections.Generic.List<T>' 需要 1 个类型参数

c# - Entity Framework 中 DBContext、DBSet<> 的引用

wpf - 在 XP 或 Vista/7 上的 VB.NET & WPF 或 WinForms 中向标题栏添加按钮(如 Firefox 4)

c# - BigInteger.ToString ("x") 没有正确打印负十六进制数

C# lambda 表达式,作用域变量值

.net - 带有嵌套聚合的Elasticsearch NEST客户端