Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Negativ bei TImage (https://www.delphipraxis.net/67595-negativ-bei-timage.html)

Martin K 17. Apr 2006 12:31


Negativ bei TImage
 
Hi,

gibt es eine einfache Möglichkeit, ein TImage negativ zu machen, also die Fraben umzukehren ?
Oder muss ich da irgendeinen komplizierten Code machen, der jedes Pixel einzeln abfragt und seinen Farbwert umkehrt?

In Paint geht das schließlich auch ganz einfach:
Bild -> Farben umkehren

Hawkeye219 17. Apr 2006 12:38

Re: Negativ bei TImage
 
Über Delphi-Referenz durchsuchenTCanvas.CopyMode dürftest Du die Lösung finden.

Gruß Hawkeye

Martin K 17. Apr 2006 12:42

Re: Negativ bei TImage
 
Danke, werd ich mal ausprobieren...

Airblader 17. Apr 2006 12:49

Re: Negativ bei TImage
 
Zitat:

Zitat von Martin K
In Paint geht das schließlich auch ganz einfach:
Bild -> Farben umkehren

Hihi,
aber beachte doch, dass du das nicht vergleichen darfst ;)
Was in Paint hinter diesem einem Klick steht weißt du doch nicht :)
Du kannst dir auch komplizierte Funktionen dafür schreiben, sie aber mit einem Klick ausführen :)

Aber wie gesagt geht es auch leichter ;)

air

Martin K 17. Apr 2006 13:48

Re: Negativ bei TImage
 
Zitat:

Zitat von Airblader
Hihi,
aber beachte doch, dass du das nicht vergleichen darfst ;)
Was in Paint hinter diesem einem Klick steht weißt du doch nicht :)
Du kannst dir auch komplizierte Funktionen dafür schreiben, sie aber mit einem Klick ausführen :)

Ja, das ist mir schon klar!
Aber so eine Funktion gibt es ja eigentlich in jedem Bildbearbeitungsprogramm.

Gibt es eigentlich auch eine Möglichkeit, nur einzelne Farben umzukehren?
Also z.B. will ich nur das, was rot in meinem Image ist (überall wo die Color=clRed ist) durch die Komlimentärfarbe von rot ersetzen.
Alles andere soll aber die alte Farbe behalten.
Ist das irgendwie möglich?

Nikolas 17. Apr 2006 13:56

Re: Negativ bei TImage
 
Das ist sicher möglich. Du könntest einfach jedes Pixel einzeln auslesen und dann neu setzen. Wobei du mit der Abfrage if pixel[x,y]=clred nicht viel Spaß haben wirst, da in einem normalen Bild sicher nur wenige Pixel exakt diese Farbe haben, das heisst, du müsstest dir einen Bereich an Farben überlegen, den du noch als 'Rot' anerkennst.

Flare 17. Apr 2006 13:57

Re: Negativ bei TImage
 
Gehen würde das, bloß die Frage ist, was definierst du als "rot"?
Etwa den RGB-Wert #FF0000?
Oder auch #DE2403?
Beides ist irgendwo "rot" :stupid:


Flare

Martin K 17. Apr 2006 14:00

Re: Negativ bei TImage
 
Ne, der Farbwert muss schon einheitlich und genau sein (kein Farbbereich).
Ich verwende Symbole, die 32x32 groß sind, also sollte die Suche nach jedem einzelnen Pixel +ersetzen auch nicht sehr lange dauern (was bei größeren Bildern vielleicht eher ein Problem sein könnte).

Martin K 17. Apr 2006 14:06

Re: Negativ bei TImage
 
Wie kann man das denn mit der Komplimentärfarbe anstellen?

Es müsste ja etwa so aussehen (bei rot): #FF0000 -> #00FFFF
Ich müsste also jedem Bereich meiner Farbe (rot grün blau) den Wert: 255-alten Wert zuweisen.

Wie kann ich denn einen Farbwert (Integer) in die Farbwerte der drei Grundfarben "zerlegen" und nachher wieder "zusammensetzen"?

heiopei 17. Apr 2006 14:12

Re: Negativ bei TImage
 
also soweit ich mich erinnere, gibts da was im delphikochbuch 6 (muss nochmal suchen).
da wird scanline verwendet (also pointer). dabei kann man auch auf jedes byte (und damit die farbwerte) zugreifen. beim negieren der farben würd ich mal auf sowas wie "nor" tippen, ich schau jetzt aber gleich nochmal nach...

bis dann,
heiopei

turboPASCAL 17. Apr 2006 14:16

Re: Negativ bei TImage
 
Einfach Scanline verwenden und die Farbwerte umdrehen, fertig.

Delphi-Quellcode:
procedure NegativeBitmapFX(aBitmap: TBitmap);
var
  x, y: integer;
  p: pbytearray;
begin
  aBitmap.PixelFormat := pf24Bit;

  for y := 0 to aBitmap.Height - 1 do
  begin
    p := aBitmap.scanline[y];
    for x := 0 to (aBitmap.Width * 3) - 1 do
      p[x] := 255 - p[x]; // oder: p[x] := not p[x];
  end;
end;

// Aufruf zB. so:

procedure TForm1.Button1Click(Sender: TObject);
begin
  NegativeBitmapFX(image1.picture.bitmap);
  image1.Refresh;
end;

// Edit:
  • Verschlimmbesserung ausgebessert.
  • Die Idee mit dem not hinzugefügt ( :gruebel: auf diese Idee währe ich im Leben nicht gekommen ;))

Martin K 17. Apr 2006 14:24

Re: Negativ bei TImage
 
Also den Code von turboPASCAL verstehe ich nicht.

Es müsste doch so gehen:
Delphi-Quellcode:
procedure Irgendwas;

    function Umkehrfarbe(const Color: TColor): TColor;
    var c1,c2,c3: Byte;
    begin
      c1 := Color div 10000;
      c2 := Color div 100 mod 100;
      c3 := Color mod 10000;
      c1 := 255-c1;
      c2 := 255-c2;
      c3 := 255-c3;
      Result := c1*10000 + c2*100 + c3;
    end;

var Color1,Color2: TColor; i,j: Integer;
begin //Color1 ist die Farbe, die umgekehrt werden soll, also z.B. clRed

Color2 := Umkehrfarbe(Color1);

for i:=1 to Image.Width do
  for j:=1 to Image.Height do
    If Image.Canvas.Pixels[i,j]=Color1 then
      Image.Canvas.Pixels[i,j]:=Color2;
end;

xaromz 17. Apr 2006 14:33

Re: Negativ bei TImage
 
Hallo,
Zitat:

Zitat von Martin K
Also den Code von turboPASCAL verstehe ich nicht.

Da ist auch was falsch.

Versuch's mal hiermit:
Delphi-Quellcode:
procedure NegativeBitmapFX(aBitmap: TBitmap);
var
  x, y: integer; // Koordinaten
  p: pbytearray; // Pixel
begin
  aBitmap.PixelFormat := pf24Bit; // Damit wir 3 Byte pro Pixel haben

  for y := 0 to aBitmap.Height - 1 do // Bildzeilen durchgehen
  begin
    p := aBitmap.scanline[y]; // Pointer auf aktuelle Zeile
    for x := 0 to (aBitmap.Width * 3) - 1 do // Jedes Pixel duchgehen (1 Pixel -> 3 Byte)
      p[x] := not p[x]; // Invertieren
  end;
end;
Wenn Du einzelne Farben prüfen willst, dann versuch Folgendes:
Delphi-Quellcode:
procedure NegativeBitmapFX(aBitmap: TBitmap);
var
  x, y: integer; // Koordinaten
  p: pbytearray; // Pixel
  R, G, B: Byte;
begin
  aBitmap.PixelFormat := pf24Bit; // Damit wir 3 Byte pro Pixel haben

  for y := 0 to aBitmap.Height - 1 do // Bildzeilen durchgehen
  begin
    p := aBitmap.scanline[y]; // Pointer auf aktuelle Zeile
    for x := 0 to aBitmap.Width - 1 do // Jedes Pixel duchgehen
    begin
      B := P[x * 3]; // Die einzelnen Farbwerte holen
      G := P[x * 3 + 1];
      R := P[x * 3 + 2];

      if R = 255 then // wenn Rotanteil voll
      begin
        P[x * 3] := not P[x * 3]; // Farbwerte invertieren
        P[x * 3 + 1] := not P[x * 3 + 1];
        P[x * 3 + 2] := not P[x * 3 + 2];
      end;
    end;
  end;
end;
Gruß
xaromz

turboPASCAL 17. Apr 2006 14:38

Re: Negativ bei TImage
 
Zitat:

Zitat von xaromz
Da ist auch was falsch.

Und was ? :gruebel:

xaromz 17. Apr 2006 14:41

Re: Negativ bei TImage
 
Hallo,
Zitat:

Zitat von turboPASCAL
Und was ? :gruebel:

Delphi-Quellcode:
 p[x] := rgb(255 - p[x], 255 - p[x], 255 - p[x]);
Du weist einem Byte einen RGB-Farbwert (Integer) zu, den Du auch noch mit dreimal dem gleichen Wert erstellst.

Gruß
xaromz

Martin K 17. Apr 2006 14:41

Re: Negativ bei TImage
 
Hab grad was festgestellt:

Das mit der Komplimentärfarbe geht ganz einfach:

Delphi-Quellcode:
function Umkehrfarbe(const Color: TColor): TColor;
begin
  Result := $FFFFFF - Color;
end;

Eichhoernchen 17. Apr 2006 14:42

Re: Negativ bei TImage
 
ich glaube der von turboPascal wird um einiges schneller sein, da Pixels[x,y] doch arg langsam ist, im gegensatz zu Scanline.

Und an deinem ist der "Nachteil" das du immer nur eine Farbe umkehren kannst, bei turbos werden alle Farben umgekehrt, so wie es glaub ich gewollt ist.

Verstehe nicht so ganz wie turboPASCAL da Scanline verwendest, ich benutze es immer so:

Delphi-Quellcode:
...

type Tpixarray = array [1..3] of byte;
var i, j : integer;
    p : ^Tpixarray;
Begin

  bitmap.pixelformat := pf24bit;

  for i := 0 to bitmap.height-1 do
   Begin
    p := fbitmap.ScanLine[i];
    for j := 0 to bitmap.width-1 do
     Begin
      p[1] := (255 - (p[1]));
      p[2] := (255 - (p[2]));
      p[3] := (255 - (p[x]));
     end;
    inc(p);
   end;
end;

xaromz 17. Apr 2006 14:44

Re: Negativ bei TImage
 
Hallo,

das ist üblicher:
Delphi-Quellcode:
function Umkehrfarbe(const Color: TColor): TColor;
begin
  // Result := not ColorToRGB(Color);
  Result := not ColorToRGB(Color) and $FFFFFF; // <-verbessert
end;
Gruß
xaromz

Martin K 17. Apr 2006 14:44

Re: Negativ bei TImage
 
Zitat:

Zitat von Eichhoernchen
Und an deinem ist der "Nachteil" das du immer nur eine Farbe umkehren kannst, bei turbos werden alle Farben umgekehrt, so wie es glaub ich gewollt ist.

Nein, nein, nein, ich will nur eine Farbe umkehren:

Zitat:

Zitat von Martin K
Gibt es eigentlich auch eine Möglichkeit, nur einzelne Farben umzukehren?
Also z.B. will ich nur das, was rot in meinem Image ist (überall wo die Color=clRed ist) durch die Komlimentärfarbe von rot ersetzen.
Alles andere soll aber die alte Farbe behalten.
Ist das irgendwie möglich?


xaromz 17. Apr 2006 14:47

Re: Negativ bei TImage
 
Hallo,
Zitat:

Zitat von Martin K
Nein, nein, nein, ich will nur eine Farbe umkehren

Dazu hab' ich doch schon was gepostet (Post #13), musst Du nur noch an Deine Bedürfnisse anpassen.

Gruß
xaromz

Martin K 17. Apr 2006 14:48

Re: Negativ bei TImage
 
Zitat:

Zitat von xaromz
Hallo,

das ist üblicher:
Delphi-Quellcode:
function Umkehrfarbe(const Color: TColor): TColor;
begin
  Result := not ColorToRGB(Color);
end;
Gruß
xaromz

Ne, das funzt irgendwie nicht.
Da bekomme ich ja negative Zahlen raus...

xaromz 17. Apr 2006 14:50

Re: Negativ bei TImage
 
Hallo,
Zitat:

Zitat von Martin K
Ne, das funzt irgendwie nicht.
Da bekomme ich ja negative Zahlen raus...

Ja, und?

Gruß
xaromz

Hawkeye219 17. Apr 2006 14:53

Re: Negativ bei TImage
 
Hier noch mal ein dezenter Hinweis auf CopyMode:

Delphi-Quellcode:
BMP.Canvas.CopyMode := cmDstInvert;
BMP.Canvas.Draw (0, 0, BMP);
Der Code invertiert das komplette Bild ohne Berücksichtigung einer Farbe.

Zitat:

Zitat von xaromz
Delphi-Quellcode:
B := P[x * 3]; // Die einzelnen Farbwerte holen
G := P[x * 3 + 1];
R := P[x * 3 + 2];

if R = 255 then // wenn Rotanteil voll

Auch bei weiß ist der Rotanteil "voll" :wink:

Gruß Hawkeye

Martin K 17. Apr 2006 14:55

Re: Negativ bei TImage
 
Zitat:

Zitat von xaromz
Hallo,
Zitat:

Zitat von Martin K
Ne, das funzt irgendwie nicht.
Da bekomme ich ja negative Zahlen raus...

Ja, und?

Gruß
xaromz

Hab mir sowas gebastelt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  If ColorDialog1.Execute then
    Form1.Color := not ColorToRGB(ColorDialog1.Color);
end;
Entweder bleibt dann die Farbe meiner Form (clBtnFace) oder sie wird schwarz.

Das hier dagegen funzt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  If ColorDialog1.Execute then
    Form1.Color := $FFFFFF-ColorDialog1.Color;
end;
Meine Form hat dann immer die Komplimentärfarbe von der im Colordialog.

turboPASCAL 17. Apr 2006 14:56

Re: Negativ bei TImage
 
Zitat:

Zitat von xaromz
Hallo,
Zitat:

Zitat von turboPASCAL
Und was ? :gruebel:

Delphi-Quellcode:
 p[x] := rgb(255 - p[x], 255 - p[x], 255 - p[x]);
Du weist einem Byte einen RGB-Farbwert (Integer) zu, den Du auch noch mit dreimal dem gleichen Wert erstellst.

Gruß
xaromz

Stimmt, ausgebessert.

Hawkeye219 17. Apr 2006 15:01

Re: Negativ bei TImage
 
Zitat:

Zitat von turboPASCAL
Stimmt, ausgebessert.

Nöö, verschlimmbessert! :wink:

Schaue Dir die x-Schleife noch mal genau an...

Gruß Hawkeye

xaromz 17. Apr 2006 15:07

Re: Negativ bei TImage
 
Hallo,

da hatte ich wohl auch einen kleinen Fehler drin. So ist's richtig:
Delphi-Quellcode:
function Umkehrfarbe(const Color: TColor): TColor;
begin
  Result := not ColorToRGB(Color) and $FFFFFF; // Erstes Byte muss null sein
end;
@Hawkeye: Das mit dem Rotanteil war ja nur ein Beispiel...

Gruß
xaromz


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz