之前我曾询问过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
答案 0 :(得分:6)
&
运算符总是不可逆的假设是不正确的。
是的,一般来说,如果你有
c = a & b
并且您知道的是c
的价值,然后您无法知道a
或b
之前的价值。
然而,&
用于从更长的值中提取某些位是很常见的,其中这些位先前与|
运算符组合在一起'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
数组先前全为零。我在内部测试中使用了%
和/
,因为它更容易理解,编译器应该转换为掩码/移位本身。通常情况下,我会做掩蔽并转移自己。