水平翻转一个比特位图线 [英] Horizontally Flip a One Bit Bitmap Line

查看:142
本文介绍了水平翻转一个比特位图线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我目前unencoding的RLE流至8位每像素缓冲区,然后重新编码为1位线,不过,我想尝试,并保持它都在1位空间,努力以增加其速度。纹表示相比于其余的节目的该部分,以相对缓慢。

例线(前翻转):

 FF FF FF FF 77 AE F0 00 

例线(后翻转):

的F7 5E EF FF FF FF F0 00 

解决方案

以下code读取和反转的数据以32位块为整数。的code键扭转位被分成两部分,因为在一个小端机器读取四个字节作为一个32位整数反转的字节顺序。

 私有静态无效的主要()
{
    VAR linelength个= 52;

    VAR输入=新的字节[] {0xFF的,为0xFF,0xFF时,为0xFF,0x77,0xAE,0XF0,0×00};
    无功输出=新的字节[input.Length]

    UInt32的lastValue = 00000000;

    变种numberBlocks = linelength个/ 32 +((linelength个%32 == 0)?0:1);
    VAR numberBitsInLastBlock = linelength个32%;

    对于(的Int32块= 0;块LT; numberBlocks;块++)
    {
        VAR rawValue = BitConverter.ToUInt32(输入,4 *块);

        变种reversedValue =(ReverseBitsA(rawValue)所述;≤(32  -  numberBitsInLastBlock))| (lastValue>> numberBitsInLastBlock);

        lastValue = rawValue;

        BitConverter.GetBytes(ReverseBitsB(reversedValue))CopyTo从(输出,4 *(numberBlocks  - 块 -  1))。
    }

    Console.WriteLine(BitConverter.ToString(输入).Replace(' - ',''));
    Console.WriteLine(BitConverter.ToString(输出).Replace(' - ',''));
}

私有静态UInt32的SwapBitGroups(UInt32的价值,UInt32的面具,的Int32移)
{
    返回((值放大器;面膜)LT;<移)| ((值放大器;〜面罩)>>移);
}

私有静态UInt32的ReverseBitsA(UInt32的值)
{
   值= SwapBitGroups(值,0x55​​555555,1);
   值= SwapBitGroups(值,0x33333333,2);
   值= SwapBitGroups(值,0x0F0F0F0F,4);

   返回值;
}

私有静态UInt32的ReverseBitsB(UInt32的值)
{
    值= SwapBitGroups(值,0x00FF00FF,8);
    值= SwapBitGroups(价值0x0000FFFF,16);

    返回值;
}
 

这是一个有点难看,反对错误的不稳健......但它仅仅是样品code。并输出以下

  FF FF FF FF 77 AE F0 00
F7 5E EF FF FF FF F0 00
 

I'm looking for an algorithm to flip a 1 Bit Bitmap line horizontally. Remember these lines are DWORD aligned!

I'm currently unencoding an RLE stream to an 8 bit-per-pixel buffer, then re-encoding to a 1 bit line, however, I would like to try and keep it all in the 1 bit space in an effort to increase its speed. Profiling indicates this portion of the program to be relatively slow compared to the rest.

Example line (Before Flip):

FF FF FF FF 77 AE F0 00

Example line (After Flip):

F7 5E EF FF FF FF F0 00

解决方案

The following code reads and reverses the data in blocks of 32 bits as integers. The code to reverse the bits is split into two parts because on a little endian machine reading four bytes as an 32 bit integer reverses the byte order.

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;
}

It is a bit ugly and not robust against errors ... but it is just sample code. And it outputs the following.

FF FF FF FF 77 AE F0 00
F7 5E EF FF FF FF F0 00

这篇关于水平翻转一个比特位图线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆