我正在寻找一种水平翻转1位位图线的算法。记住这些行是DWORD对齐的!
我目前正在将RLE流编码为每像素8位缓冲区,然后重新编码为1位线,但是,我想尝试将其全部保存在1位空间中提高速度。分析表明该程序的这一部分与其余部分相比相对较慢。
示例行(翻转前):
FF FF FF FF 77 AE F0 00
示例行(翻转后):
F7 5E EF FF FF FF F0 00
答案 0 :(得分:1)
创建转换表以交换字节中的位:
byte[] convert = new byte[256];
for (int i = 0; i < 256; i++) {
int value = 0;
for (int bit = 1; bit <= 128; bit<<=1) {
value <<= 1;
if ((i & bit) != 0) value++;
}
convert[i] = (byte)value;
}
现在您可以使用该表交换一个字节,然后您只需将该字节存储在结果中的正确位置:
byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0xAE, 0xF0, 0x00 };
int width = 52;
int shift = data.Length * 8 - width;
int shiftBytes = data.Length - 1 - shift / 8;
int shiftBits = shift % 8;
byte[] result = new byte[data.Length];
for (int i = 0; i < data.Length; i++) {
byte swap = convert[data[i]];
if (shiftBits == 0) {
result[shiftBYtes - i] = swap;
} else {
if (shiftBytes - i >= 0) {
result[shiftBytes - i] |= (byte)(swap << shiftBits);
}
if (shiftBytes - i - 1 >= 0) {
result[shiftBytes - i - 1] |= (byte)(swap >> (8 - shiftBits));
}
}
}
Console.WriteLine(BitConverter.ToString(result));
输出:
F7-5E-EF-FF-FF-FF-F0-00
答案 1 :(得分:1)
以下代码以32位的块为整数读取和反转数据。反转位的代码分为两部分,因为在一个小端的机器上读取四个字节作为32位整数反转字节顺序。
private static void Main()
{
var lineLength = 52;
var input = new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0xAE, 0xF0, 0x00 };
var output = new Byte[input.Length];
UInt32 lastValue = 0x00000000;
var numberBlocks = lineLength / 32 + ((lineLength % 32 == 0) ? 0 : 1);
var numberBitsInLastBlock = lineLength % 32;
for (Int32 block = 0; block < numberBlocks; block++)
{
var rawValue = BitConverter.ToUInt32(input, 4 * block);
var reversedValue = (ReverseBitsA(rawValue) << (32 - numberBitsInLastBlock)) | (lastValue >> numberBitsInLastBlock);
lastValue = rawValue;
BitConverter.GetBytes(ReverseBitsB(reversedValue)).CopyTo(output, 4 * (numberBlocks - block - 1));
}
Console.WriteLine(BitConverter.ToString(input).Replace('-', ' '));
Console.WriteLine(BitConverter.ToString(output).Replace('-', ' '));
}
private static UInt32 SwapBitGroups(UInt32 value, UInt32 mask, Int32 shift)
{
return ((value & mask) << shift) | ((value & ~mask) >> shift);
}
private static UInt32 ReverseBitsA(UInt32 value)
{
value = SwapBitGroups(value, 0x55555555, 1);
value = SwapBitGroups(value, 0x33333333, 2);
value = SwapBitGroups(value, 0x0F0F0F0F, 4);
return value;
}
private static UInt32 ReverseBitsB(UInt32 value)
{
value = SwapBitGroups(value, 0x00FF00FF, 8);
value = SwapBitGroups(value, 0x0000FFFF, 16);
return value;
}
它有点难看并且不能抵御错误...但它只是示例代码。它输出以下内容。
FF FF FF FF 77 AE F0 00
F7 5E EF FF FF FF F0 00