之前我曾经问过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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
宽度,高度,图像解压缩和图像压缩长度始终相同.
当这个功能完成后,我把图像(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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:格式为32bppRGB
&操作员总是不可逆的假设是不正确的.
是的,一般情况下,如果你有
c = a & b
Run Code Online (Sandbox Code Playgroud)
和所有你知道的价值c,那么你可以不知道什么值a或b前手了.
然而,&用于从较长值中提取某些位是非常常见的,其中这些位先前与|运算符组合在一起,并且每个"位字段"彼此独立.与通用&或|运算符的基本区别使得这种可逆性是原始位预先全为零,并且字中的其他位保持不变.即:
0xc0 | 0x03 = 0xc3 // combine two nybbles
0xc3 & 0xf0 = 0xc0 // extract the top nybble
0xc3 & 0x0f = 0x03 // extract the bottom nybble
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您当前的功能似乎是提取每像素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
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:假设图像是8像素宽的倍数,该dest_image数组先前全为零.我已经使用%并/在内部测试,因为它更容易理解和编译器应该转换为掩盖/移动本身.通常情况下,我会做掩蔽并改变自己.
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |