Entwickler-Ecke

Multimedia / Grafik - Negativ eines Bildes erstellen


Delete - Mi 19.01.05 15:30
Titel: Negativ eines Bildes erstellen
Guten Tag.

Ich hätte gerne ein Tutorial, einen Algorithmus oder einen Delphibefehl, mit dem man das Negativ eines Bildes, zB BMP, erstellen kann.
Bin im Forum und bei Google leider nicht fündig geworden.

Mfg

10f10

Moderiert von user profile iconUdontknow: Status auf "Erledigt" gesetzt.


BenBE - Mi 19.01.05 15:39

Mit BitBlt ist dies möglich, wenn du den XOR-Modus auf eine weiße Grundfläche machst. IIRC.


HolgerB - Mi 19.01.05 16:05

Graphics32 hat dafür auch eine Prozedur an Bord und bietet noch viele weitere tolle und vor allem Schnelle funktionen.

http://graphics32.org/documentation/Docs/Units/GR32_Filters/Routines/Invert.htm


Delete - Mi 19.01.05 16:53

Ich habe den Befehl gerade ausprobiert:


Delphi-Quelltext
1:
BitBlt(PaintBox1.Canvas.Handle,0,0,80,108,Image1.Canvas.Handle,0,0,SRCINVERT);                    


Allerdings funktioniert das Ganze nicht wie gewünscht. Bei mir konvertiert er weiß in so ein hässliches hellbraun. Selbst ein komplett weißes Image ist hinterher hellbraun.
Nun habe ich ein anderes Win-Theme und wenn ich auf Windows-Klassisch stelle wird das Bild auch schwarz, aber es kann ja nicht sein, dass ein Schwarz-Weiß Bild nicht in Weiß-Schwarz konvertiert wird, sondern in ein blaulila-hellbraun Bild..

Die Graphics32 Komponenten habe ich auch. Bisher bin ich aber noch nicht an dem Problem weiter gekommen, wie man TBitmap und TBitmap32 zueinander konvertiert.

One


GiO - Di 25.01.05 18:35


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm1.invertClick(Sender: TObject);
   function InvertBitmap(MyBitmap: TBitmap): TBitmap;
   var
     x, y: Integer;
     ByteArray: PByteArray;
   begin
     MyBitmap.PixelFormat := pf24Bit;
     for y := 0 to MyBitmap.Height - 1 do
     begin
       ByteArray := MyBitmap.ScanLine[y];
       for x := 0 to MyBitmap.Width * 3 - 1 do
       begin
         ByteArray[x] := 255 - ByteArray[x];
       end;
     end;
     Result := MyBitmap;
   end;
begin
  Image4.Picture.Bitmap := InvertBitmap(Image4.Picture.Bitmap);
  BMPbackground.Assign(Image4.Picture.Bitmap);
  Image4.Refresh;
end;


So mach ich es..

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


Delete - Di 25.01.05 18:49

Danke, funktioniert super

Gruß 10F10


Lossy eX - Di 25.01.05 20:12

Mir ist da gerade was an dem Quellcode aufgefallen. Du übergibst ein Bitmap als Parameter. Und lieferst dann noch ein Mal diese Instanz zurück. Das Zurückgeben und nochmalige zuweisen des Bitmaps kannst du dir sparen, da bei Klassen alles sofort auf die Klasseninstanz übertragen wird. Wenn du also lediglich die Rückgabe und Zuweisung des Bitmaps weg lässt, dann funktioniert dennoch alles wie bisher. Das macht auch den anderen Code schmaler.

Ich habe noch etwas. Ich weiß. Ich bin ein scheußlicher Perfektionist. ;-)

Zum Invertieren könnte man den Algorithmus noch optimieren. Also wenn man das unbedingt wollen würde. ;-)
Wenn man diese Zeile

Delphi-Quelltext
1:
ByteArray[x] := 255 - ByteArray[x];                    

durch diese ersetzt

Delphi-Quelltext
1:
ByteArray[x] := not ByteArray[x];                    

dann invertiert er das Byte. Das Ergebnis ist das Selbe obwohl keine Rechenoperation notwendig ist.

PS: Wenn man es ganz wahnsinnig mag, dann kann man das ganze auch als DWORD invertieren. Da der Prozessor 32Bit Register hat kann man so mehr Daten auf einen Schlag invertieren. Dann müsste man aber noch die letzten Bytes in der Zeile als Bytes invertieren. So eine Optimierung ist im Speicherkopieren von Delphi eingebaut.


myukew - Di 01.02.05 16:49

nur weil man einen boolschen operator anwendet heißt das noch lange nicht dass man keine rechenoperation braucht. ich wär mir gar nicht so sicher dass das so viel schneller gehtschneller geht.
und die sache mit den dwords sollte ein ordentlicher compiler auch seber merken

imho


I.MacLeod - Di 01.02.05 18:00

myukew hat folgendes geschrieben:
nur weil man einen boolschen operator anwendet heißt das noch lange nicht dass man keine rechenoperation braucht.


Klar braucht er eine. Nur ist es ein "not" statt "sub".

myukew hat folgendes geschrieben:
und die sache mit den dwords sollte ein ordentlicher compiler auch seber merken


Wohl eher nicht, da so tiefgreifende Optimierungen nicht so ohne weiteres zu implementieren sind (insbesondere mit annehmbarer Geschwindigkeit) und hier außerdem noch eine Anpassung am Quelltext notwendig wäre, um mit DWORDs zu arbeiten (es sei denn man wechselt vorher auf 32bit/Pixel [was natürlich vom Compiler erst recht nicht erkannt werden kann ;-)], aber dann würde ja auch noch das vierte Byte verändert, was wieder zu irgendwelchen Problemen führen könnte/würde)

//Edit:

Jetzt hab ich vor lauter Aufregung das vergessen was ich eigentlich posten wollte:

Suche im MSDN INVERTRECT


F34r0fTh3D4rk - Mi 02.02.05 17:29

so viel schneller geht schneller geht :P

schönes echo :)