Pixelweise Bildbearbeitung: Unterschied zwischen den Versionen
Aus DGL Wiki
(Die Seite wurde neu angelegt: == Zugriff durch Canvas.Pixels == Vorteile: * Sehr einfach anzuwenden * Funktioniert für alle Farbtiefen/Pixelformate * Geringes risiko falsche Bereiche zu überschrei...) |
|||
Zeile 21: | Zeile 21: | ||
Nachteile: | Nachteile: | ||
* Bei komplexeren Manipulationen umständlich | * Bei komplexeren Manipulationen umständlich | ||
− | * Kein zugriff über x,y | + | * Kein zugriff über x,y -Koordinate |
* Hohes Risiko falsche Bereiche zu überschreiben | * Hohes Risiko falsche Bereiche zu überschreiben | ||
− | * Für 24BPP ungünstig, da es keinen 3byte großen primitiven typ gibt. | + | * Man muss den code für jedes Pixelformat extra erstellen. |
+ | * Für 24BPP ungünstig, da es keinen 3byte großen primitiven typ gibt. (Geschwindigkeitsvorteiteil gegenüber Arraymethode sinkt) | ||
+ | |||
+ | Beschreibung: | ||
+ | Man holt sich mittels der scanline eigenschaft des Bitmaps einen direkten zeiger auf die zeilenanfänge. Mittels Zeigermanipulation bearbeitet man anschließend die Pixeldaten. Das ist natürlich sehr schnell, besonders für 8,16 und 32bit. Man kann jedoch nur schwer mittels koordinaten auf einzelne pixel zugreifen, man arbeitet die pixel üblicherweise in zeilen nacheinander ab. Es ist außerdem Vorsicht geboten, damit man nicht unabsichtlich über den Datenbereich hinaus liest/schreibt. | ||
Beispiel: | Beispiel: | ||
+ | Type TPixel=packed record B,G,R:byte; | ||
procedure Invert(bmp:TBitmap); | procedure Invert(bmp:TBitmap); | ||
− | |||
var p:^TPixel; | var p:^TPixel; | ||
x,y:integer; | x,y:integer; | ||
Zeile 44: | Zeile 48: | ||
end; | end; | ||
end; | end; | ||
+ | |||
+ | == Zugriff mittels dynamischer arrays == | ||
+ | Vorteile: | ||
+ | * Schnell | ||
+ | * Flexibel (Uugriff über x,y-Koordinate) | ||
+ | Nachteile | ||
+ | * Mittleres Risiko falsche Bereiche zu überschreiben | ||
+ | * Man muss den code für jedes Pixelformat extra erstellen. | ||
+ | |||
+ | Beispiel: | ||
+ | Type TPixel=packed record b,g,r;end; | ||
+ | TPixelArray=array[0..715827881]of TPixel;//Knapp unter 2GB | ||
+ | PPixelArray=^TPixelarray; | ||
+ | TPixels=array of PPixelarray; | ||
+ | procedure invert(bmp:TBitmap); | ||
+ | var Pixels: |
Version vom 17. Juli 2007, 14:48 Uhr
Zugriff durch Canvas.Pixels
Vorteile:
- Sehr einfach anzuwenden
- Funktioniert für alle Farbtiefen/Pixelformate
- Geringes risiko falsche Bereiche zu überschreiben
Nachteile:
- Sehr langsam
Beispiel:
procedure Invert(bmp:TBitmap); var x,y:integer; begin for y:=0 to bmp.height-1 do for x:=0 to bmp.width-1 do bmp.canvas.pixels[x,y]:=bmp.canvas.pixels[x,y]xor $FFFFFF; end;
Zugriff mittels scanline
Vorteile:
- Sehr schnell
Nachteile:
- Bei komplexeren Manipulationen umständlich
- Kein zugriff über x,y -Koordinate
- Hohes Risiko falsche Bereiche zu überschreiben
- Man muss den code für jedes Pixelformat extra erstellen.
- Für 24BPP ungünstig, da es keinen 3byte großen primitiven typ gibt. (Geschwindigkeitsvorteiteil gegenüber Arraymethode sinkt)
Beschreibung: Man holt sich mittels der scanline eigenschaft des Bitmaps einen direkten zeiger auf die zeilenanfänge. Mittels Zeigermanipulation bearbeitet man anschließend die Pixeldaten. Das ist natürlich sehr schnell, besonders für 8,16 und 32bit. Man kann jedoch nur schwer mittels koordinaten auf einzelne pixel zugreifen, man arbeitet die pixel üblicherweise in zeilen nacheinander ab. Es ist außerdem Vorsicht geboten, damit man nicht unabsichtlich über den Datenbereich hinaus liest/schreibt.
Beispiel:
Type TPixel=packed record B,G,R:byte; procedure Invert(bmp:TBitmap); var p:^TPixel; x,y:integer; begin if bmp.pixelformat<>pf24bit then raise exception.create('Pixelformat not supported'); for y:=0 to bmp.height-1 do begin p:=bmp.scanline[y]; for x:=0 to bmp.width-1 do begin p.r:=p.r xor $FF; p.g:=p.g xor $FF; p.b:=p.b xor $FF; inc(p);//3 Byte weiter end; end; end;
Zugriff mittels dynamischer arrays
Vorteile:
- Schnell
- Flexibel (Uugriff über x,y-Koordinate)
Nachteile
- Mittleres Risiko falsche Bereiche zu überschreiben
- Man muss den code für jedes Pixelformat extra erstellen.
Beispiel:
Type TPixel=packed record b,g,r;end; TPixelArray=array[0..715827881]of TPixel;//Knapp unter 2GB PPixelArray=^TPixelarray; TPixels=array of PPixelarray; procedure invert(bmp:TBitmap); var Pixels: