AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi [GR32] How to add intensity?
Thema durchsuchen
Ansicht
Themen-Optionen

[GR32] How to add intensity?

Ein Thema von WojTec · begonnen am 22. Jan 2010 · letzter Beitrag vom 12. Jun 2010
Antwort Antwort
Seite 2 von 3     12 3      
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#11

Re: [GR32] How to add intensity?

  Alt 22. Jan 2010, 20:19
@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).
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#12

Re: [GR32] How to add intensity?

  Alt 22. Jan 2010, 20:22
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.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#13

Re: [GR32] How to add intensity?

  Alt 23. Jan 2010, 12:01
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:
Row.R := (Color.R * Row.R) div 255;
Row.G := (Color.G * Row.G) div 255;
Row.B := (Color.B * Row.B) div 255;
Example output from my code:

(see 1.png, left part - 0%)

Now output with @Medium proposition:

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;

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);
(see 1.png)

And @jfheins (or maybe I don't understand your formula and coded wrong?):

Delphi-Quellcode:
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)));
(see 2.png)
Miniaturansicht angehängter Grafiken
2_133.png   1_102.png  
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#14

Re: [GR32] How to add intensity?

  Alt 23. Jan 2010, 16:27
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#15

Re: [GR32] How to add intensity?

  Alt 23. Jan 2010, 18:28
This is procedure:

Delphi-Quellcode:
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;
After your latest suggestion percenta parameter work fine

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
Miniaturansicht angehängter Grafiken
3_472.png  
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#16

Re: [GR32] How to add intensity?

  Alt 23. Jan 2010, 19:22
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:
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;
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.
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#17

Re: [GR32] How to add intensity?

  Alt 25. Jan 2010, 12:55
Wow, thanks! It working! Man, lets teach me graphic processing 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 von Medium:
suggestion by the JPEG commité

Brightness := (0.299*Bits.R + 0.587*Bits.G + 0.114*Bits.B)/765;
I thought this is NTSC suggestion?
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?
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#18

Re: [GR32] How to add intensity?

  Alt 25. Jan 2010, 14:25
Zitat von WojTec:
How you learn it?
This might sound old, but I learned by doing. I have a general interest in graphics, so my spare time projects often are somehow related. And every time I hit a wall, I fire up good ole oncle google and find something eventually -> *pow* knowledge enhanced
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:
I thought this is NTSC suggestion?
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?
Could be that this originated with NTSC. I encountered it first when I had to deal with the details of JPEG . That the "flat" (sum/3) approach appears darker is understandable. Why the weighted formula also results in a darker image might be cause by that you probably have R and B switched. Bitmap data in memory is usually stored in BGR order, not RGB. Thus simply switching R with B in your TColor32Entry record will probably correct this.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#19

Re: [GR32] How to add intensity?

  Alt 25. Jan 2010, 14:58
Delphi-Quellcode:
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;
There are not my symbols, there are in GR32. I'm using this record in all filters and look to be correct
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#20

Re: [GR32] How to add intensity?

  Alt 25. Jan 2010, 15:14
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
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:09 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