Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Aus Intensität neue Farbe berechnen (https://www.delphipraxis.net/54968-aus-intensitaet-neue-farbe-berechnen.html)

glkgereon 14. Okt 2005 10:57


Aus Intensität neue Farbe berechnen
 
Hi

ich habe ein TBitmap, einen 2D Array of Byte und eine Hintergrundfarbe.

ich möchte nun das auf jedes Pixel eines neues TBitmap die Farbe des alten Bitmaps mit der Intensität des jeweiligen Bytes gegenüber der Hintergrundfarbe errechnet wird.
ich hoffe das war soweit verständlich :)

also ein paar beispiele:

HGFarbe = Rot
AltPixel = Blau

Byte = 255
=> NeuPixel = Blau
Byte = 0
=> NeuPixel = Rot
Byte = 128
=> NeuPixel = Lila

gibt es sowas?

marabu 14. Okt 2005 11:50

Re: Aus Intensität neue Farbe berechnen
 
Hallo Gereon,

du suchst einen Color Fading Algorithmus? Da gibt es verschiedene. Da ich gerade keinen Zugriff auf meine Fachbibliothek habe, hier nur die Idee: Du musst für jedes Pixel im Bild die RGB-Differenz bestimmen, indem du DeltaRed aus PixelRed - BackgroundRed bildest - DeltaBlue und DeltaGreen analog. Die Intensität der Farbe im neuen Pixel errechnet sich dann aus dem Shift-Wert aus deinem ByteArray und dem Delta, indem du NewRed aus BackgroundRed + DeltaRed * Shift / 255 berechnest, die anderen Farbwerte wieder analog. Ist nicht viel Code, aber Optimieren lohnt sich. Bestimmt findest du sogar etwas Fertiges mit den richtigen Suchbegriffen.

Grüße vom marabu

Mist - Vorzeichen war vertauscht...

glkgereon 14. Okt 2005 12:13

Re: Aus Intensität neue Farbe berechnen
 
ja, mit etwas überlegen bin ich letztendlich auf folgendes Code gekommen (Die beiden ersten kommen aus der Codelib):

Delphi-Quellcode:
function RGB2TColor(const R, G, B: Byte): Integer;
begin
  // convert hexa-decimal values to RGB
  Result := R + G shl 8 + B shl 16;
end;


procedure TColor2RGB(const Color: TColor; var R, G, B: Byte);
begin
  // convert hexa-decimal values to RGB
  R := Color and $FF;
  G := (Color shr 8) and $FF;
  B := (Color shr 16) and $FF;
end;

function FadeColor(Cl, BGCl: TColor; Fade: Byte):TColor;
var CR, CG, CB, HR, HG, HB: Byte;
begin
  TColor2RGB(CL,CR,CG,CB);
  TColor2RGB(BGCl,HR,HG,HB);
  CR:=(CR*Fade+HR*(256-Fade)) div 256;
  CG:=(CG*Fade+HG*(256-Fade)) div 256;
  CB:=(CB*Fade+HB*(256-Fade)) div 256;
  Result:=RGB2TColor(CR,CG,CB);
end;
ich weiss nicht ob er funktioniert, da er für meine Anwendung offensichtlich deutlich zu langsam ist und es nur flackert, ohne das man was erkennen kann.
ich werde heute abend nochmal genau testen...

Dax 14. Okt 2005 12:22

Re: Aus Intensität neue Farbe berechnen
 
div 256? :shock: Mach das zu shr 8 und es sollte deutlich schneller werden ;)

DerDan 14. Okt 2005 12:28

Re: Aus Intensität neue Farbe berechnen
 
Ich wollt blos mal mekern:

Zitat:

CR:=(CR*Fade+HR*(256-Fade)) div 256;
muss eigendlich:

CR:=(CR*Fade+HR*(255-Fade)) div 255;

lauten, da Fade einen Umfang von 0..255 hat !


mfg

DerDan

ripper8472 14. Okt 2005 12:29

Re: Aus Intensität neue Farbe berechnen
 
das optimiert der compiler schon weg. wichtiger waere ein OR statt + in der oberen funktion.

leute, benutzt mehr bitoperationen!!

Khabarakh 14. Okt 2005 13:32

Re: Aus Intensität neue Farbe berechnen
 
Und natürlich kein Pixels benutzen :wink: .
Oder ganz schnell :mrgreen: :
Delphi-Quellcode:
// GR32-Lib, [url]www.graphics32.org[/url]
// Unit GR32_Blend
// "Note, that after using the Blend function, you have to call EMMS. Otherwise CPU will be unable to handle floating point instructions."

function M_BlendReg(F, B: TColor32): TColor32;
asm
  // blend foregrownd color (F) to a background color (B),
  // using alpha channel value of F
  // EAX <- F
  // EDX <- B
  // Result := Fa * (Frgb - Brgb) + Brgb
        db $0F,$6E,$C0           /// MOVD     MM0,EAX
        db $0F,$EF,$DB          /// PXOR     MM3,MM3
        db $0F,$6E,$D2           /// MOVD     MM2,EDX
        db $0F,$60,$C3           /// PUNPCKLBW MM0,MM3
        MOV    ECX,bias_ptr
        db $0F,$60,$D3           /// PUNPCKLBW MM2,MM3
        db $0F,$6F,$C8           /// MOVQ     MM1,MM0
        db $0F,$69,$C9           /// PUNPCKHWD MM1,MM1
        db $0F,$F9,$C2           /// PSUBW    MM0,MM2
        db $0F,$6A,$C9           /// PUNPCKHDQ MM1,MM1
        db $0F,$71,$F2,$08       /// PSLLW    MM2,8
        db $0F,$D5,$C1           /// PMULLW   MM0,MM1
        db $0F,$FD,$11           /// PADDW    MM2,[ECX]
        db $0F,$FD,$D0           /// PADDW    MM2,MM0
        db $0F,$71,$D2,$08       /// PSRLW    MM2,8
        db $0F,$67,$D3           /// PACKUSWB MM2,MM3
        db $0F,$7E,$D0           /// MOVD     EAX,MM2
end;
Vielleicht kann das ja jemand auf "Intensität" statt Alphakanal von F umschreiben. Ich habe jedenfalls keine Ahnung von Assembler, von MMX noch weniger.

himitsu 14. Okt 2005 13:48

Re: Aus Intensität neue Farbe berechnen
 
Zitat:

Zitat von DerDan
Ich wollt blos mal mekern:

Zitat:

CR:=(CR*Fade+HR*(256-Fade)) div 256;
muss eigendlich:

CR:=(CR*Fade+HR*(255-Fade)) div 255;

lauten, da Fade einen Umfang von 0..255 hat !


mfg

DerDan


Fast richtig :warn:

div 256 muß bleiben, da 0 bis 255 = 256.


Code:
CR := (CR * Fade + HR * (25[color=red]5[/color]-Fade)) div 25[color=red]6[/color];
und falls es unbedingt wer will, obwohl es die Codeoptimierung ja auch so ändert ^^
Code:
CR := (CR * Fade + HR * (25[color=red]5[/color]-Fade)) [color=red]shr 8[/color];

marabu 14. Okt 2005 16:20

Re: Aus Intensität neue Farbe berechnen
 
Hallo Leute,

der von mir formulierte Algorithmus in der Formelsprache von Gereon lautet:

Delphi-Quellcode:
CR := HR + (CR - HR) * FADE / 255;
Sei CR = 200 und HR = 20. Bei meinem ersten Testfall ist FADE = 255 und ich erwarte, dass CR sich dann nicht ändert. Bei einem FADE von 0 erwarte ich, dass CR zu HR wird. Und bei einem FADE von 102 erwarte ich eine 40-prozentige Intensität für CR vor HR - rechnerisch 92. Bekommt ihr das mit euren Berechnungen hin?

Nachdenkliche Grüße vom marabu

glkgereon 14. Okt 2005 19:37

Re: Aus Intensität neue Farbe berechnen
 
also

CR = 100
HR = 10

CR = HR + (CR - HR) * FADE / 255

Fade = 0
CR = 10 + (100-10)*0/255 = 10 //Korrekt

Fade = 255
CR = 10 + (100-10)*255/255 = 10+ (100-10) = 100 //Korrekt


CR = (CR*Fade + HR*(255-Fade)) / 255;

Fade = 0
CR = (100*0 + 10*(255-0)) / 255 = 10*255/255 = 10 //Korrekt

Fade = 255
CR = (100*255 + 10*(255-255))/255 = 100*255/255 = 100 //Korrekt

beide korrekt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:27 Uhr.
Seite 1 von 2  1 2      

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