![]() |
Re: [GR32] How to add intensity?
@Medium, after exchanges this values, 0% is solid color output.
When intensity is 100% image should be 100% in Color tone, when 50% - in 50% Color tone and 50% original colors (look image). |
Re: [GR32] How to add intensity?
If this is not what you get after the change, please post the whole part of your source. Otherwise we won't come far here. I won't ask for it a third time, since the code you provided had little to do with the Lerp() function, and as such can't relate to the problem. (It should work as well if you handled each channel separately, as already said.)
|
Re: [GR32] How to add intensity?
Liste der Anhänge anzeigen (Anzahl: 2)
Ok, let's start from begining. What I need: I want to add color filter to image with intensity parameter. Output should be like on image from post #3. My current code:
Delphi-Quellcode:
Example output from my code:
Row.R := (Color.R * Row.R) div 255;
Row.G := (Color.G * Row.G) div 255; Row.B := (Color.B * Row.B) div 255; (see 1.png, left part - 0%) Now output with @Medium proposition:
Delphi-Quellcode:
(see 1.png)
function Lerp(a, b: Byte; t: Double): Byte;
var tmp: Double; begin tmp := t*a + (1-t)*b; if tmp<0 then result := 0 else if tmp>255 then result := 255 else result := Round(tmp); end; Row.R := Lerp(Color.R, (Color.R * Row.R) div 255, APercent / 100); Row.G := Lerp(Color.G, (Color.G * Row.G) div 255, APercent / 100); Row.B := Lerp(Color.B, (Color.B * Row.B) div 255, APercent / 100); And @jfheins (or maybe I don't understand your formula and coded wrong?):
Delphi-Quellcode:
(see 2.png)
B := (Row.R + Row.G + Row.B) div 3;
Row.R := IntToByte(Round((1 - (APercent / 100)) * Row.R + (APercent / 100) * (Color.R * B))); Row.G := IntToByte(Round((1 - (APercent / 100)) * Row.G + (APercent / 100) * (Color.G * B))); Row.B := IntToByte(Round((1 - (APercent / 100)) * Row.B + (APercent / 100) * (Color.B * B))); |
Re: [GR32] How to add intensity?
As I already said, change the line
tmp := t*a + (1-t)*b; to tmp := (1-t)*a + t*b; Another thing is, that it's not clear to me, which variable holds the original color. Color or Row? If it's Row, then change Row.R := Lerp(Color.R, (Color.R * Row.R) div 255, APercent / 100); to Row.R := Lerp(Row.R, (Color.R * Row.R) div 255, APercent / 100); And yet another thing unclear to me is, if your initial formula does create the desired effect or not. If it isn't, then my code of course cannot function! It isn't really clear what your problem was: Just the ability to apply it at different percentages, or this AND the formula. Edit: Scrub the last part, the formula itself looks fine. The two changes above should do well if I interpret the output correctly. |
Re: [GR32] How to add intensity?
Liste der Anhänge anzeigen (Anzahl: 1)
This is procedure:
Delphi-Quellcode:
After your latest suggestion percenta parameter work fine :D
var
Bits: PColor32Entry; Color: TColor32Entry; I, J: Integer; Percent: Single; begin Color.ARGB := Color32(AColor); Percent := APercent / 100; Bits := @ASource.Bits[0]; for I := 0 to ASource.Height - 1 do begin for J := 0 to ASource.Width - 1 do begin Bits.R := Lerp(Bits.R, (Color.R * Bits.R) div 255, Percent); Bits.G := Lerp(Bits.G, (Color.G * Bits.G) div 255, Percent); Bits.B := Lerp(Bits.B, (Color.B * Bits.B) div 255, Percent); Inc(Bits); end; end; ASource.Changed; end; But my formula don't makes filter I want... My EN is too poor to explain better what I want :( But I'll try: you have glass with specific color, when you look by this glass you see image in this glass color tone. When you use more thin glass (percent parameter has less value) in same color, you see more origanl image colors, but image you see stay in this glass color tone. Are you understand? I want to obtain filter like this glass. In graphics software you can see this filter, for example in PSP (Effects->Photo effects->Film and filters). "Row" I used with TBitpam.ScanLine() and forgot change name ;) |
Re: [GR32] How to add intensity?
Aha! You basically want a color tint. The 100% formula for this is:
Brightness := (original.R + original.G + original.B)/(3*255) // normalized to 0..1 NewColor := RGB(tint.R*Brightness, tint.G*Brightness, tint.B*Brightness) That is what jfheins already wrote, I suppose your implementation had rounding issues or did not normalize brightness (I'm too lazy to verfy this now :)). This should do the trick:
Delphi-Quellcode:
As a refinement, you could calculate the brightness weighted according to the suggestion by the JPEG commité, that accounts for green being percieved brightest, followed by red and blue darkest at equal values.
var
Bits: PColor32Entry; Color: TColor32Entry; I, J: Integer; Percent: Single; Brightness: Single; begin Color.ARGB := Color32(AColor); Percent := APercent / 100; Bits := @ASource.Bits[0]; for I := 0 to ASource.Height - 1 do begin for J := 0 to ASource.Width - 1 do begin Brightness := (Bits.R+Bits.G+Bits.B)/765; Bits.R := Lerp(Bits.R, Round(Brightness * Color.R), Percent); Bits.G := Lerp(Bits.G, Round(Brightness * Color.G), Percent); Bits.B := Lerp(Bits.B, Round(Brightness * Color.B), Percent); Inc(Bits); end; end; ASource.Changed; end; The line Brightness := (Bits.R+Bits.G+Bits.B)/765; would then look like Brightness := (0.299*Bits.R + 0.587*Bits.G + 0.114*Bits.B)/765; It's a few operations more, but might improve the result notably. |
Re: [GR32] How to add intensity?
Wow, thanks! It working! Man, lets teach me graphic processing :D How you learn it? I want too! Could you suggest some good sources?
Output is a bit darker than input, but can it correct with next filters ;) Zitat:
Also uotput is very dark with this brightness version. I used it early to remove colors and output is always lighter than classic Sum(RGB)/3. So why here is darker? |
Re: [GR32] How to add intensity?
Zitat:
I couldn't even recommend any general sources or books, since all I do is basically self-taught by doing, fiddeling around and reading stuff on the internet. It certainly wasn't a matter of days or weeks though ;) Zitat:
|
Re: [GR32] How to add intensity?
Delphi-Quellcode:
There are not my symbols, there are in GR32. I'm using this record in all filters and look to be correct :)
property Bits: PColor32Array read FBits;
TColor32Array = array [0..0] of TColor32; TColor32Entry = packed record case Integer of 0: (B, G, R, A: Byte); 1: (ARGB: TColor32); 2: (Planes: array[0..3] of Byte); 3: (Components: array[TColor32Component] of Byte); end; function Color32(WinColor: TColor): TColor32; overload; {$IFDEF WIN_COLOR_FIX} var I: Longword; {$ENDIF} begin {$IFDEF CLX} WinColor := ColorToRGB(WinColor); {$ELSE} if WinColor < 0 then WinColor := GetSysColor(WinColor and $000000FF); {$ENDIF} {$IFDEF WIN_COLOR_FIX} Result := $FF000000; I := (WinColor and $00FF0000) shr 16; if I <> 0 then Result := Result or TColor32(Integer(I) - 1); I := WinColor and $0000FF00; if I <> 0 then Result := Result or TColor32(Integer(I) - $00000100); I := WinColor and $000000FF; if I <> 0 then Result := Result or TColor32(Integer(I) - 1) shl 16; {$ELSE} asm MOV EAX,WinColor BSWAP EAX MOV AL,$FF ROR EAX,8 MOV Result,EAX end; {$ENDIF} end; |
Re: [GR32] How to add intensity?
Mh, then there is no obvious reason for this darkening. You could use your reference output and compare a white-tinted image (= implicit conversion to grayscales) of just a pure red, green and blue area to derive the weights they used, to make your output similar to it. That is, if you approve of the reference :)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:48 Uhr. |
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