在给定的指针地址读取 3 个字节的最快方法?
Posted
技术标签:
【中文标题】在给定的指针地址读取 3 个字节的最快方法?【英文标题】:Fastest way to read 3 bytes at a given pointer address? 【发布时间】:2013-02-26 06:32:02 【问题描述】:我目前正在读取位图的像素数据,使用锁定位图后可用的BitmapData
。我使用的方法分别读取每个颜色字节,并且比直接在给定指针处读取 4 字节 int
慢。但不幸的是,我的位图是 24bpp,这意味着每个像素有 3 个字节,而不是 4 个。那么有没有办法快速读取 3 个字节并将其转换为给定指针地址的int
?
// read pixel color
byte* Pix = (byte*)bmpScan0 + (y * bmpStride) + (x * 3);
byte R = *(Pix + 2);
byte G = *(Pix + 1);
byte B = *(Pix);
int RGB = ((int)R << 16) | ((int)G << 8) | (int)B;
【问题讨论】:
@MitchWheat 啊,很好的观点;位图像素格式到处都是字节顺序...... 您的示例代码与您的要求不一致 - 它显示将 3 个字节读取到单独的变量中,而不是int
并屏蔽 8 个最高位......还可以考虑显示更多代码 -一个你看起来像做很多数学以获得下一个字节的方法。
@AlexeiLevenkov - 我更新了我的代码以显示我需要实现的目标。
在我看来不像 C# :P
【参考方案1】:
您可以在像素地址读取完整的 int 并屏蔽掉额外的字节,而不是多个操作 - 读取、屏蔽等。
int Pix = *(int*)((byte*)bmpScan0 + (y * bmpStride) + (x * 3)) & 0x00FFFFFF;
根据您的字节顺序,您可能需要向下移动而不是屏蔽,并且您的颜色分量可能会反转 - BGR 而不是 RGB。
哦,由于从未与 4 字节边界对齐的内存中读取,您可能会遇到一些速度问题。您可以解决这些问题,但解决方案通常比最初的问题更糟糕。
【讨论】:
+1。我相信这是正确的方法(显然不需要计算“当前”像素,因为+=3
应该做“下一步”的事情)......但是@Geotarget 已经在 JerKimball 的回答中驳回了这种方法 - 所以不清楚 OP 正在寻找什么.
OP 驳回了答案,因为它没有用 1 行代码读取 3 个字节。我真的不需要 R/G/B 拆分字节。我只是使用它,因为我别无选择。
@Geotarget - 我认为是这样的。【参考方案2】:
你的意思是这样的:
int foo = *(some pixel address in memory);
byte R = (byte)(foo & 0xff0000 >> 16);
byte G = (byte)(foo & 0x00ff00 >> 8);
byte B = (byte)(foo & 0xff);
编辑:应保留此答案未经编辑以保持其他 cmets 的连续性,但基于对问题本身的编辑不再适用。 :)
【讨论】:
我的代码已经比这个方法快了。我正在寻找甚至更快的东西。以上是关于在给定的指针地址读取 3 个字节的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章
x86-64 上检查指针范围是不是跨越 N 字节对齐地址的最快方法?
为什么一个指针在32位系统中占4个字节,在64位系统中占8个字节?