【问题标题】:C# Convert or compare int to (unsafe) byte*C# 将 int 转换或比较为(不安全)字节*
【发布时间】:2019-03-15 15:13:11
【问题描述】:

原始场景

我严重误解了自己的代码,这种情况是无效的。

这与我的正常驾驶室不同,所以我会解释得最好 我能。

我有一个用户设置的颜色代码。示例:

int R = 255;
int G = 255;
int B = 255; 

我有很多大图像需要检查颜色 某些坐标集上的像素与用户设置的颜色相对。一世 可以成功获取图片中任意像素的byte*,并获取 我期望的值。

我使用来自Bitmap.LockBits(...)BitmapData 执行此操作。我的 理解是锁定对性能很重要 原因。会有很多这样的例子被使用 跨越非常大的图像集合,因此性能是主要的 考虑。

出于同样的性能原因,我试图避免将 检索由不安全字节表示为整数的像素颜色 - 我会 而是一次将我的 int 转换为一个字节并将其用于 可能会在每次运行时针对数百万像素运行 调用。

但是...我无法弄清楚如何获取任何用户设置的整数 进入一个不安全字节(byte*)并将其与不安全字节进行比较 从像素中检索。

不安全字节 (byte*) 是像素数据的 8 位指针(至少,我是这么理解的),但我将单个颜色作为常规旧字节获取。

byte* pixel = //value here pulled from image;
pixel[2] //red value byte
pixel[1] //green value byte
pixel[0] //blue value byte

所以我不需要将我的ints 转换为不安全字节...指针?...,只需一个简单的Converter.ToByte(myInt)


真正的问题

但是由于我认为这仍然可能是我的场景之外的一个有效问题,所以我将把这部分留给别人来回答,希望将来能帮助别人:

如何在 C# 中获取任何给定的 int 并将其与“不安全字节”指针“byte*”进行比较?

【问题讨论】:

  • 顺便说一句,没有不安全的字节,byte* 是一个指向(正常)字节的指针,不安全的东西(在它需要unsafe 关键字的意义上)正在使用指针
  • 您可以从位图中获取颜色。颜色 color = bitmap.GetPixel(x, y); Int32 rgb = color.ToArgb();
  • @harold 我开始认为我根本不明白我在这里要做什么......主要不是 C# 开发人员,所以这对我来说是不同的。
  • @jdweng 是的,但出于性能原因,我认为我应该避免使用GetPixel,至少这是我读过的文档让我相信的。
  • 如果您锁定 ARGB 格式,您甚至可以使用 int* 并同时比较整个像素,而不是分别处理 R G 和 B

标签: c# int byte unsafe


【解决方案1】:

让我们打开一个位图并处理每个像素

//Note this has several overloads, including a path to an image
//Use the proper one for yourself
Bitmap b = new Bitmap(_image);

//Lock(and Load baby) 
BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

//Bits per pixel, obviously
byte bitsPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat);

//Gets the address of the first pixel data in the bitmap.
//This can also be thought of as the first scan line in the bitmap.
byte* scan0 = (byte*)bData.Scan0.ToPointer();

for (int i = 0; i < bData.Height; ++i)
{
    for (int j = 0; j < bData.Width; ++j)
    {
        byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
        //data is a pointer to the first byte of the 3-byte color data
        //Do your magic here, compare your RGB values here 
         byte R = *b;     //Dereferencing pointer here
         byte G = *(b+1); 
         byte B = *(b+2); 
    }
}
//Unlocking here is important or memoryleak
b.UnlockBits(bData);

【讨论】:

    【解决方案2】:

    您只想取消引用字节指针并将其与整数进行比较。

    unsafe void Main()
    {
        byte x = 15;
        int y = 15;
        Console.WriteLine(AreEqual(&x, y)); // True
    }
    
    public unsafe bool AreEqual(byte* bytePtr, int val) {
        var byteVal = *bytePtr;
        return byteVal == val;
    }
    

    【讨论】:

    • 完全可行,但我关心的是性能——我在每次调用时将数百万或数十亿个指针转换为 vars,或者仅将三个整数转换为指针。虽然我相信我可能严重误解了指针的工作原理,但我通常开发前端,或者至少在后端没有这么深。
    • @RandyHall 您可以将整数转换为指针,但最终如果要比较它们指向的值,则需要取消引用它们。如果比较指针,除非指向相同的地址,否则它们将不相等。如果在上面的代码中添加Console.WriteLine(&amp;x == &amp;y);,您将比较指针,结果将是错误的。它们指向不同的地址,因此它们不相等。 Console.WriteLine(*(&amp;x) == *(&amp;y)); 是正确的,因为您正在取消引用并比较它们指向的值。
    猜你喜欢
    • 2022-12-06
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2013-11-23
    • 2016-03-04
    • 2016-02-20
    相关资源
    最近更新 更多