如何扭转这个功能

时间:2009-04-26 07:34:55

标签: c#

之前我曾询问过Bitwise AND(&)的相反情况,你告诉我它无法逆转。

嗯,情况就是这样:服务器发送一个图像,用我想要反转的函数编码,然后用zlib编码。

这是我从服务器获取图像的方式:

        UInt32[] image = new UInt32[200 * 64];
        int imgIndex = 0;
        byte[] imgdata = new byte[compressed];
        byte[] imgdataout = new byte[uncompressed];

        Array.Copy(data, 17, imgdata, 0, compressed);
        imgdataout = zlib.Decompress(imgdata);
        for (int h = 0; h < height; h++)
        {
            for (int w = 0; w < width; w++)
            {
                imgIndex = (int)((height - 1 - h) * width + w);
                image[imgIndex] = 0xFF000000;
                if (((1 << (Int32)(0xFF & (w & 0x80000007))) & imgdataout[((h * width + w) >> 3)]) > 0)
                {
                    image[imgIndex] = 0xFFFFFFFF;
                }
            }
        }

宽度,高度,图像解压缩和图像压缩长度始终相同。

当这个功能完成后,我把图像(UInt32 []数组)放在一个位图中,我就知道了。

现在我想成为服务器并发送该图像。我必须做两件事:

反转该功能,然后用zlib压缩它。

如何反转该功能以便对图片进行编码?

    for (int h = 0; h < height; h++)
    {
        for (int w = 0; w < width; w++)
        {
            imgIndex = (int)((height - 1 - h) * width + w);
            image[imgIndex] = 0xFF000000;
            if (((1 << (Int32)(0xFF & (w & 0x80000007))) & imgdataout[((h * width + w) >> 3)]) > 0)
            {
                image[imgIndex] = 0xFFFFFFFF;
            }
        }
    }

编辑:格式为32bppRGB

1 个答案:

答案 0 :(得分:6)

&运算符总是不可逆的假设是不正确的。

是的,一般来说,如果你有

c = a & b

并且您知道的是c的价值,然后您无法知道ab之前的价值。

然而,&用于从更长的值中提取某些位是很常见的,其中这些位先前与|运算符组合在一起'bit field'是彼此独立的。与通用&|运算符的根本区别在于,这可以使原始位事先全为零,并且字中的其他位保持不变。即:

0xc0 | 0x03 = 0xc3   // combine two nybbles

0xc3 & 0xf0 = 0xc0   // extract the top nybble
0xc3 & 0x0f = 0x03   // extract the bottom nybble

在这种情况下,您当前的功能似乎是提取每像素1位(单色图像)并将其转换为32位RGBA。

你需要这样的东西:

int source_image[];
byte dest_image[];

for (int h = 0; h < height; ++h) {
    for (int w = 0; w < width; ++w) {
        int offset = (h * width) + w;
        if (source_image[offset] == 0xffffffff) {
            int mask = w % 8; // these two lines convert from one int-per-pixel
            offset /= 8;      // offset to one-bit-per-pixel
            dest_image[offset] |= (1 << mask); // only changes _one_ bit
        }
    }
}

注意:假设图像是8像素宽的倍数,dest_image数组先前全为零。我在内部测试中使用了%/,因为它更容易理解,编译器应该转换为掩码/移位本身。通常情况下,我会做掩蔽并转移自己。