问题描述
我有一些C / C ++代码,其中有一个16位数字(uint16_t
),我需要将前5位与后5位交换,并保持它们的从左到右顺序每块5位。中间的6位需要保持不变。我不擅长按位数学/运算,所以将不胜感激!
从概念上讲,职位转换看起来像:
ABCDEFGHIJKLMnop
变为LMnopFGHIJKABCDE
或更确切地说...
10101000000001010
变成0101000000010101
。
任何帮助将不胜感激!
解决方法
首先,您应该检查所使用的任何库是否尚未为R5G6B5像素进行RGB-BGR交换。
这里是您在问题中所写内容的字面翻译。实时视频可能太慢了:
uint16_t rgbswap(uint16_t in) {
uint16_t r = (in >> 11) & 0b011111;
uint16_t g = (in >> 5) & 0b111111;
uint16_t b = (in >> 0) & 0b011111;
return b << 11 | g << 5 | r << 0;
}
,
您无需将输入分为3个单独的R,G和B组件,而是可以通过移至较高位来并行处理R和B
uint16_t rgb2bgr(uint16_t in)
{
uint16_t r0b = in & 0b1111100000011111;
uint16_t b0r = ((r0b << 22) | r0b) >> 11;
return b0r | (in & 0b11111100000);
}
另一种使用乘法来交换R和B的替代方法
uint16_t rgb2bgr_2(uint16_t in)
{
uint16_t r0b = in & 0b1111100000011111;
uint16_t b0r = r0b * 0b1000000000000000000000100000 >> 16;
return b0r | (in & 0b11111100000);
}
基本上是this technique,对于提取位或在周围移动位很有用
您可以检查compiled result on Godbolt来查看乘法方法产生的输出较短,但这仅在具有快速乘法器的情况下有用