Pixelweise Bildbearbeitung: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
Zeile 52: Zeile 52:
 
Vorteile:
 
Vorteile:
 
* Schnell
 
* Schnell
* Flexibel (Uugriff über x,y-Koordinate)
+
* Flexibel (Zugriff über x,y-Koordinate)
 
Nachteile
 
Nachteile
 
* Mittleres Risiko falsche Bereiche zu überschreiben
 
* Mittleres Risiko falsche Bereiche zu überschreiben
Zeile 62: Zeile 62:
 
       PPixelArray=^TPixelarray;
 
       PPixelArray=^TPixelarray;
 
       TPixels=array of PPixelarray;
 
       TPixels=array of PPixelarray;
  procedure invert(bmp:TBitmap);
+
  procedure Invert(bmp:TBitmap);
  var Pixels:
+
  var Pixels:TPixels;
 +
    x,y:integer;
 +
begin
 +
  //Pixels initialisieren
 +
  setlength(Pixels,bmp.height);
 +
  for y:=0 to bmp.height-1 do
 +
  Pixels[y]:=bmp.scanline[y];
 +
  //Bild bearbeiten
 +
  for y:=0 to bmp.height-1 do
 +
  for x:=0 to bmp.width-1 do
 +
    begin
 +
    Pixels[y,x].r:=Pixels[y,x].r xor $FF;
 +
    Pixels[y,x].g:=Pixels[y,x].g xor $FF;
 +
    Pixels[y,x].b:=Pixels[y,x].b xor $FF;
 +
    end;
 +
end;
 +
 
 +
procedure Grayscale(bmp:TBitmap);
 +
var Pixels:TPixels;
 +
    x,y:integer;
 +
begin
 +
  //Pixels initialisieren
 +
  setlength(Pixels,bmp.height);
 +
  for y:=0 to bmp.height-1 do
 +
  Pixels[y]:=bmp.scanline[y];
 +
  //Bild bearbeiten
 +
  for y:=0 to bmp.height-1 do
 +
  for x:=0 to bmp.width-1 do
 +
    begin
 +
    Pixels[y,x].r:=(Pixels[y,x].r+Pixels[y,x].g+Pixels[y,x].b)div 3;
 +
    Pixels[y,x].g:=Pixels[y,x].r;
 +
    Pixels[y,x].b:=Pixels[y,x].r;
 +
    end;
 +
end;

Version vom 17. Juli 2007, 15:56 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 (Zugriff ü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:TPixels;
    x,y:integer;
begin
 //Pixels initialisieren
 setlength(Pixels,bmp.height);
 for y:=0 to bmp.height-1 do
  Pixels[y]:=bmp.scanline[y];
 //Bild bearbeiten
 for y:=0 to bmp.height-1 do
  for x:=0 to bmp.width-1 do
   begin
    Pixels[y,x].r:=Pixels[y,x].r xor $FF;
    Pixels[y,x].g:=Pixels[y,x].g xor $FF;
    Pixels[y,x].b:=Pixels[y,x].b xor $FF;
   end;
end;
procedure Grayscale(bmp:TBitmap);
var Pixels:TPixels;
    x,y:integer;
begin
 //Pixels initialisieren
 setlength(Pixels,bmp.height);
 for y:=0 to bmp.height-1 do
  Pixels[y]:=bmp.scanline[y];
 //Bild bearbeiten
 for y:=0 to bmp.height-1 do
  for x:=0 to bmp.width-1 do
   begin
    Pixels[y,x].r:=(Pixels[y,x].r+Pixels[y,x].g+Pixels[y,x].b)div 3;
    Pixels[y,x].g:=Pixels[y,x].r;
    Pixels[y,x].b:=Pixels[y,x].r;
   end;
end;