![]() |
[GR32] How to add intensity?
I have simple procedure to add color filter to bitmap:
Delphi-Quellcode:
How to add Intensity parameter (0=original color, 100=as above)?
Row.R := (Color.R * Row.R) div 255;
// Repeat for G and B Or maybe is better method to colorize filter? |
Re: [GR32] How to add intensity?
I haven't really understood what you do with this particular filter, but it looks like you're looking for simple linear interpolation, where you can shift beween two values freely.
Delphi-Quellcode:
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; procedure YourFilter(Percent: Integer); begin Row.R := Lerp(Color.R, (Color.R*Row.R) div 255, Percent/100); //... end; |
Re: [GR32] How to add intensity?
Liste der Anhänge anzeigen (Anzahl: 1)
Something similar (Lerp() coloring too much - up to solid color). I mean like this:
![]() :) |
Re: [GR32] How to add intensity?
I would do something like this:
1. You have the "target color" (full brightness and saturation) and the amount you want to blend (between 0 and 1) 2. For each Pixel do: 2.1: multiply the target color with the brightness of the image pixel 2.2: mix the image pixel and the result from 2.1 together, according to the amount. :arrow: (1-x) * image_pixel + x * (color * image_pixel_brightness) The Brigness of a pixel is calculated by adding up all the components and dividung the result by 3. However, there is an advanced formula that weights the colors differently. |
Re: [GR32] How to add intensity?
Hi!
@WojTec: Could you please attach the image instead of including it in the posting? This would decrease loading times and the thread is still useful, even if the image has gone on the other server. Thanks in advance. Bye, Frederic |
Re: [GR32] How to add intensity?
Zitat:
|
Re: [GR32] How to add intensity?
@jfheins, I'm doing something wrong :(:
Delphi-Quellcode:
@fkerber, Ok, I'll remmeber.
var
Row: PBGRAQuad; Color: TBGRAQuad; I, J: Integer; B: Byte; C: TColor; begin Color := ColorToTriple24(AColor); Row := PBGRAQuad(@ASource.Bits[0]); for I := 0 to ASource.Height - 1 do begin for J := 0 to ASource.Width - 1 do begin B := (Row.R + Row.G + Row.B) div 3; C := TColor(Round((1 - (APercent / 100)) * RGB(Row.R, Row.G, Row.B) + (APercent / 100) * (RGB(Color.R, Color.G, Color.B) * B))); Row.R := GetRValue(C); Row.G := GetGValue(C); Row.B := GetBValue(C); Inc(Row); end; end; end; |
Re: [GR32] How to add intensity?
@Medium, when Color is for example clYellow and 3rd parameter is 1, any pixel of output is = Color. This is wrong - should be as is on example image above.
|
Re: [GR32] How to add intensity?
Hi!
Zitat:
You could also do so in the above posting. It's possible by editing the posting (To do this, click on the button "edit" in the upper right corner). Bye, Frederic |
Re: [GR32] How to add intensity?
Zitat:
Regarding the code you posted: You cannot simply multiply with whole combined RGB-values. You must handle each color channel separately. |
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 :)
|
AW: [GR32] How to add intensity?
Hello again. I have yet another question in this topic. How to add option "preserve luminosity" to our tint procedure? Currently working very well, but I want to apply tint as creative filter - now my tint working as in PS or PSP but with unchecked "preserve luminosity". Please help :)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:28 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