水平翻转一位位图线

时间:2010-05-05 21:28:50

标签: algorithm bitmap

我正在寻找一种水平翻转1位位图线的算法。记住这些行是DWORD对齐的!

我目前正在将RLE流编码为每像素8位缓冲区,然后重新编码为1位线,但是,我想尝试将其全部保存在1位空间中提高速度。分析表明该程序的这一部分与其余部分相比相对较慢。

示例行(翻转前):

FF FF FF FF 77 AE F0 00

示例行(翻转后):

F7 5E EF FF FF FF F0 00

2 个答案:

答案 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