Directory Contents Search << >>


DaVinci 4: Leonardo: Pixelweiser DIB-Zugriff

Mit der RWxxxx Gruppe von Leonardo Funktionen können Sie DIBs leicht lesen und schreiben ohne sich um Details der zugrundeliegenden Strukturen kümmern zu müssen.

Für die Bearbeitung von DIBs mit 16 Bit je Farbkomponente Farbtiefe oder im CMYK-Farbformat ist diese Funktionsgruppe die einzig empfehlenswerte Methode.

Konzept

Eröffnen einer DIB zum Schreiben und Lesen

Um die DIB-Pixel mit hoher Geschwindigkeit verarbeiten zu können, legt RWOpenDIB zusätzliche Informationen über die DIB in einem Cache ab. Daher muss das Cache-Handle vom Typ HDIBRW zunächst von Leonardo erstellt werden.

HDIB

hDIB;

HDIBRW

hRW = RWOpenDIB(hDIB);

Lesen/Schreiben von einzelnen Pixeln

Die Anwendung kann nun die Pixel in der DIB adressieren. Für den Zugriff auf Pixel-Ebene stehen folgende Funktionen zur Verfügung:

RWGetPixel / RWSetPixel lehnt sich so weit als möglich an die Windows API-Funktion GetPixel an.

RWGetPixelRGB16 / RWSetPixelRGB16 erlaubt den Zugriff auf Pixel mit 16 Bit Genauigkeit je Farbkanal. Anwendungen sollten der Verwendung dieser Funktion den Vorzug gegenüber RWGetPixel geben.

RWGetPixelIndex / RWSetPixelIndex erlaubt den Zugriff auf die Pixeldaten im Original-Datenformat der DIB. Es wird dazu eine PIXELINDEXUNION-Struktur ausgefüllt, wobei der Bedeutung des Inhalts von den Feldern biBitCount und biPlanes der mit RWOpenDIB geöffneten DIB abhängt. Da die Umwandlung der Daten in ein RGB-Format entfällt, ist dieser Zugriff schneller als der Zugriff über die anderen Funktionen, insbesondere beim Setzen von Pixeln in DIBs mit 4 oder 8 Bit Farbtiefe. Anwendungen sollten diesen Funktionen den Vorzug geben, wenn Pixel lediglich kopiert werden sollen, wobei die aktuelle RGB-Bedeutung der Pixel nicht analysiert werden muss.

COLORREF cr;

RGBQUAD16 rgbq16;

// Beispiel: Pixelwert invertieren.

cr = RWGetPixel(hRW, x, y);

cr = RGB( 255 GetRValue (cr),

255 GetGValue (cr),

255 GetBValue (cr) );

RWSetPixel(hRW, x, y, cr);

// Dasselbe mit RGBQ16

RWGetPixelRGB16 (hRW, x, y, &rgbq16);

rgbq.rgb16Red = 65535 rgbq.rgb16Red;

rgbq.rgb16Green = 65535 rgbq.rgb16Green;

rgbq.rgb16Blue = 65535 rgbq.rgb16Blue;

RWSetPixelRGB16(hRW, x, y, &rgbq16);

Lesen/Schreiben von ganzen DIB-Zeilen

Um noch schneller auf die Pixel einer DIB zugreifen zu können, kann die Anwendung auch eine ganze Zeile einer DIB oder Teile davon als RGBQUAD16-Strukturen bearbeiten.

Dazu stellt die Anwendung ein Array von RGBQUAD16-Strukturen zur Verfügung.

#define BLOCK_SIZE

256

RGBQUAD16 argbq[BLOCK_SIZE];

BITMAPINFOHEADER bmi;

UINT x, i;

DIBInfo(hDib, &bmi, sizeof(bmi));

for (x=0; x<bmi.biWidth; ++x)

{

RWGetLineRGB16(hRW, x, y, BLOCK_SIZE, argbq);

for (i=0; i<BLOCK_SIZE; ++i)

{

argbq[i].rgbq16Red = 65535 argbq[i].rgbq16Red

argbq[i].rgbq16Green = 65535 argbq[i].rgbq16Green

argbq[i].rgbq16Blue = 65535 argbq[i].rgbq16Blue

}

RWSetLineRGB16(hRW, x, y, BLOCK_SIZE, argbq);

}

Zeichnen mit Windows HDC Gerätekontext

Für komplexere Zeichenoperationen kann die Anwendung mit der Funktion RWGetDC einen Windows-DC für die DIB anfordern und dann Zeichenoperationen durchführen. Dies ist auch dann möglich, wenn die zugrundeliegende DIB DaVinci-Erweiterungen benutzt wie DIBs im CMYK-Fargbraum, mit 16 Bit Genauigkeit je Farbkanal oder mit Alpha-Kanal. Nach Abschluß der Zeichenvorgänge muss die Anwendung den Windows DC mit RWReleaseDC wieder freigeben.

{ HDC hDC = RWGetDC(hRW);

LPCSTR text="Einfach in eine DIB Zeichnen!";

TextOut(hDC, 100, 100, text, lstrlen(text));

RWReleaseDC(hRW, hDC);

}

Abschließen des DIB-Zugriffs

Wenn die Anwendung keine weiteren DIB-Zugriffe ausführen will, muss sie das von RWOpenDIB zurückgelieferte Handle mit der Funktion RWClose freigeben.

Performance-Überlegungen

Die Routinen der RWxxxx Gruppe sind auf eine hohe Arbeitsgeschwindigkeit optimiert, erreichen aber natürlich nicht die Geschwindigkeit von Zugriffen, die die Anwendung direkt in den Speicher durchführt.

Die RWGetDC / RWReleaseDC-Funktionen führen zu Beginn und Ende der Zeichenoperation einen Kopiervorgang durch und sind daher langsam, insbesondere wenn die DIB den CYMK-Farbraum verwendet.

Besonders langsam ist das Setzen von Pixeln nach einem RGB-Wert in eine DIB mit Farbpalette (biBitCount=4 oder biBitCount=8) sowie bei monochromen DIBs bei denen die Farbpalette andere Werte als "schwarz" und "weiß" enthält. In diesem Fall muss die Funktion RWSetPixelRGB16 zunächst den besten Farbpaletteneintrag für den RGB-Wert bestimmen, ein sehr zeitraubender Vorgang. Ist der Wert für ein RGB-Pixel einmal bestimmt, wird er in einem 256 KByte großen Block für den nächsten möglichen Zugriff vorgehalten.

Für zwei besonders wichtige Sonderfällen von Farbpaletten enthält Leonardo Optimierungen, die das Setzen von Paletteneinträgen erheblich beschleunigen.

Eine quadratische 6*6*6 RGB-Farbpalette mit 17 Zusätzlichen Graustufen wie sie von DitherTo8 und CreateDIB erstellt wird.

Eine Grauwerttreppe mit rgb[PaletteIndex] = PaletteIndex wie sie von GrayDIB erstellt wird.