# 16 Bit Graustufen ausgeben



## Trendy Andy (17. November 2004)

Ich möchte ein Bild mit 16 Bit pro Pixel ausgeben. Jedoch habe ich keine geeignete Funktion gefunden um 16 Bit Grautöne darzustellen. 
Mit StretchDIBits() kann ich 8 Bit Grautöne ausgeben, jedoch keine 16 Bit (oder mach ich da was falsch?). Kann mir jemand helfen?

PS: Ich arbeite mit VC 6.0 + MFC


----------



## Trendy Andy (18. November 2004)

Hat keiner ne Ahnung?


----------



## Tobias K. (18. November 2004)

moin


Beim 12. Parameter kann man DIB_PAL_COLORS (für 16Bit) als Parameter mitgeben, vielleicht hilft das ja.


mfg
umbrasaxum


----------



## Trendy Andy (18. November 2004)

Das hab ich auch schon probiert. jedoch klappts nicht. Er kompiliert zwar, aber es wird immer falsch angezeigt!
Wenn ich nur bei StretchDIBits() auf DIB_PAL_COLORS umstelle kommt "Pixelgulasch" raus.
Wenn ich im BITMAPINFOHEADER diBitCount auf 16 setze erscheint zwar das Bild, aber nicht schwarz/weis sondern in einem grün-,blau- oder rotton.
Wenn ich noch biCompression = BI_BITFIELDS setze zeigt er gar kein bild mehr an.

Die Optionen sind wahrscheinlich nur für 16 Bit Farbwerte aber nicht für 16 Grautöne.


----------



## Tobias K. (18. November 2004)

moin


16 Bit ist auch noch kein schwarz weiss, versteh jetzt nciht mehr genau was du machen willst.


mfg
umbrasaxum


----------



## Trendy Andy (18. November 2004)

Ich zeig die Grautöne zur Zeit mit Hilfe der RGB Farbpalette an. Ein Grauton entsteht immer wenn die Werte für R, G und B gleich sind (z.B. ff ff ff für weis). R, G oder B gehen jedoch nur von 0 bis 255, also kann ich nur 256 Grautöne damit Darstellen. Ich bräuchte aber quasi eine Farbpalette mit der ich 16 Bit Grautöne darstellen kann.


----------



## Endurion (18. November 2004)

Huppala, das geht nicht, nicht mit dem Windows jetzt. 

Windows kann bis jetzt nur 32bit maximale Farbtiefe am Desktop, da ist kein Platz für 16bit-Grautöne. Du kannst die Darstellung allerdings hinfaken, indem du Dithering benutzt, also quasi die 16bit-Grautöne als geditherte 8bit-Grautöne darstellen lässt. Das sieht bei der üblichen hohen Auflösung dann auf jeden Fall besser aus als pure 8bit-Grautöne.


----------



## Trendy Andy (18. November 2004)

Und wie mach ich das? Mit Dithering kenn ich mich nicht aus.

Mit dem Programm ImageJ kann ich 16 Bit RAW Files öffnen und 16Bit Grautöne (dann wahrscheinlich gefakete 16Bit) anzeigen. Das Programm ist ein opensource programm. Leider kenn ich mich in java net so doll aus um da funktionen zu extrahieren.


----------



## Endurion (19. November 2004)

Uije, das kann man billig und einfach, oder kompliziert machen. Ich hab mich bei meinem Programm für billig und einfach entschieden 

Ich habe von einem Farbwert die "überflüssigen" Bits (also die Bits, die bei der direkten Umrechnung verloren gehen, bei 16bit die unteren 8) als Index in mehrere Dithermusterflächen benutzt. Ich habe so ein Dithering bei einer Umrechnung von 24bit auf 16bit benutzt. Da gehen ja nur 3 bit pro Farbe verloren, aber das Prinzip ist dasselbe.

Wenn du irgendwelche unteren 8 bits gesetzt hast, liegt dein Farbwert ja zwischen dem "abgeschnittenen Wert" (nur die oberen 8 bits) und dem nächsthöheren Farbwert (nur die oberen 8 bits + 1). Die einzelnen Dithermuster waren bei mir einfach ein Schema (4x4 Pixel, je nach Index waren verschieden viele Pixel in dem Schema gesetzt - möglichst gleichmässig verteilt).
Wenn ich jetzt ein Schema anwenden musste, dann habe ich das Offset des umzurechnenden Pixels im Schema gesucht, und wenn dort ein Pixel gesetzt war, habe ich den nächsthöheren Wert (von den 8 oberen Bits + 1) genommen. Andernfalls den direkten Wert. Sieht recht annehmlich aus.


----------



## Trendy Andy (19. November 2004)

Kannst du ein stück quell text posten?


----------



## Endurion (19. November 2004)

Is nix schönes, die Ausgangssituation ist ein 24bit RGB-Feld, Ziel ist ein 16bit (555) RGB-Feld:


```
int             i,
                  j;

  WORD            wWidth,
                  wHeight;

  
  unsigned char   ucPart[3];

  static BYTE     ucPattern[8][4][4] =
  { { { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 } },
  { { 1, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 1, 0 },
  { 0, 0, 0, 0 } },
  { { 0, 0, 0, 0 },
  { 0, 1, 0, 1 },
  { 0, 0, 0, 0 },
  { 0, 1, 0, 1 } },
  { { 1, 0, 1, 0 },
  { 0, 0, 0, 1 },
  { 1, 0, 1, 0 },
  { 0, 1, 0, 0 } },
  { { 1, 0, 1, 0 },
  { 0, 1, 0, 1 },
  { 1, 0, 1, 0 },
  { 0, 1, 0, 1 } },
  { { 0, 1, 0, 1 },
  { 1, 1, 1, 0 },
  { 0, 1, 0, 1 },
  { 1, 0, 1, 1 } },
  { { 0, 1, 0, 1 },
  { 1, 1, 1, 1 },
  { 0, 1, 0, 1 },
  { 1, 1, 1, 1 } },
    { { 1, 1, 1, 1 },
  { 1, 0, 1, 1 },
  { 1, 1, 1, 1 },
  { 1, 1, 1, 0 } } };


  CConvertOptions   coDlg;

  coDlg.DoModal();


  wWidth = pImageSource->GetWidth();
  wHeight = pImageSource->GetHeight();
  int iR,iG,iB;
  for ( j = 0; j < (int)wHeight; j++ )
  {
    for ( i = 0; i < (int)wWidth; i++ )
    {
      ucPart[0] = pSourceData[3 * i + j * 3 * wWidth];
      ucPart[1] = pSourceData[3 * i + j * 3 * wWidth + 1];
      ucPart[2] = pSourceData[3 * i + j * 3 * wWidth + 2];

          // Dithering
          iR = ( ucPart[0] >> 3 ) + ucPattern[ucPart[0] & 0x07][i % 4][j % 4];
          iG = ( ucPart[1] >> 3 ) + ucPattern[ucPart[1] & 0x07][i % 4][j % 4];
          iB = ( ucPart[2] >> 3 ) + ucPattern[ucPart[2] & 0x07][i % 4][j % 4];
          if ( iR > 31 )
          {
            iR = 31;
          }
          if ( iG > 31 )
          {
            iG = 31;
          }
          if ( iB > 31 )
          {
            iB = 31;
          }
          ( (WORD*)pTargetData)[i + j * wWidth] = 
            ( iR ) + 
            ( iG << 5 ) + 
            ( iB << 10 );
    }
  }
```

ucPattern sind die Dithermuster. Bei 1 kommt ein Pixel der höheren Farbe hin, bei 0 nicht.

Beachte ucPart[0] & 0x07. Das nimmt die abzuschneidenden Bits (3 bits) und benutzt die als Index in die Dithermuster.

Das % 4 bei i und j kachelt quasi die Dithermuster über dem Bild, so dass die Pixel-Verteilung übernommen wird. Weder effizient noch besonder schöner Code, klappt aber herfürragend.

edit: Stell dir vor, es gibt Foren, und die benutzen alle dieselben Code-Tags!


----------



## Trendy Andy (19. November 2004)

Ich dank dir erstmal. Ich werde den Code dann mal am Wochenende ausprobieren.


----------

