2009-04-26 14 views
0

Ich habe vorher über das Gegenteil von Bitwise AND (&) gefragt und Sie sagten mir, dass es unmöglich ist, umzukehren.Wie man diese Funktion umkehrt

Nun, das ist die Situation: Der Server sendet ein Bild, das mit der Funktion codiert ist, die ich umkehren will, dann ist es mit zlib codiert. Dieses

ist, wie ich das Bild vom Server erhalten:

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

Breite, Höhe, Bildkomposition und dekomprimiert und Bilddruck Länge ist immer gleich.

Wenn diese Funktion fertig ist, legte ich Bild (UInt32 [] Array) in eine Bitmap und ich habe es.

Jetzt möchte ich den Server sein und senden, dass image.I zwei Dinge zu tun haben:

diese Funktion umkehren und es dann mit zlib komprimieren.

Wie kann ich diese Funktion umkehren, damit ich das Bild kodieren kann?

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

EDIT: Das Format ist 32bppRGB

+2

"und du hast mir gesagt, dass es unmöglich ist umzukehren" ... Denkst du, dass SO eine Art Borg Kollektiv ist? :) – BobbyShaftoe

+0

Ich denke immer noch nicht, dass Sie es umkehren können. & ist nicht umkehrbar wie du gesagt hast, auch wenn du & mit einer Konstante.Obwohl ich vielleicht falsch liege, könnte das Testen eines Bildes [i] == 0xFFFFFFFF bedeuten, dass es die Bedingung erfüllt hat, also können Sie vielleicht etwas daraus entnehmen. –

+0

Diese Funktion konvertiert byte [] in rohe bitmapdata.Thats alles was sie tut –

Antwort

6

Die Annahme, dass die & Betreiber immer irreversibel ist falsch.

Ja, in der Regel, wenn Sie

c = a & b 

und alles, was Sie wissen müssen, ist der Wert von c, dann wissen Sie nicht, was a oder b vor der Hand hatte Werte.

aber es & sehr häufig ist, um zu Extrakt bestimmte Bits von einem längeren Wert verwendet werden, wobei diese Bits, die zuvor zusammen mit dem | Operator und wo jedes ‚Bit-Feld‘ ist von jedem anderen unabhängigem kombiniert wurden. Der grundlegende Unterschied zu den generischen Operatoren & oder |, der dies reversibel macht, besteht darin, dass die ursprünglichen Bits vorher alle waren und die anderen Bits im Wort unverändert bleiben. d.h:

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

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

In diesem Fall Ihre aktuelle Funktion erscheint ein 1-Bit-pro-Pixel zu extrahieren (monochromes Bild) und in 32-Bit RGBA umwandelt.

Sie werden so etwas wie benötigen:

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

NB: annimmt das Bild ein Vielfaches von 8 Pixel breit, dass die dest_image Array war zuvor alle Nullen. Ich habe % und / in diesem inneren Test verwendet, weil es einfacher zu verstehen ist und der Compiler in Maske/Shift selbst konvertieren sollte. Normalerweise würde ich die Maskierung und Verschiebung selbst vornehmen.

+0

Danke, diese Frage ist sowieso tot. Ich werde Ihren Code verwenden und wenn ein Problem auftreten. Ich werde erneut fragen. –

+0

Edit: Die Breite beträgt 200, die Höhe ist 64. Bitmap BMP = neue Bitmap (200, 64, 800, PixelFormat.Format32bppRgb, neue IntPtr (ptr)); –

+0

Kam zum selben Schluss so yup. Das scheint es zu sein. –