Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Vignette effect (https://www.delphipraxis.net/154568-vignette-effect.html)

WojTec 15. Sep 2010 17:57


Vignette effect
 
Hello. I want to draw vignette effect, but don't have idea how to do this? For graphics I'm using GR32. Could you help?

mkinzler 15. Sep 2010 18:08

AW: Vintage effect
 
What do you think of "vintage Effect"?

WojTec 15. Sep 2010 18:13

Re: Vignette effect
 
Sorry, I used bad word :cry: I mean vignette. I now corrected.

sx2008 16. Sep 2010 00:56

AW: Vignette effect
 
You could calculate the brightness of every Pixel with a 2-dimensional Gaussian function.
Here is some Pseudocode:
Delphi-Quellcode:
xcenter := Bitmap.Width div 2;
ycenter := Bitmap.Height div 2;
for each Pixel do
begin
  brightness_factor := mygaussian(x - xcenter, y-ycenter)* 0.5{=effect depth} + 0.3{basic brightness};
  Pixel[x,y].red  := Pixel[x,y].red * brightness_factor;
  Pixel[x,y].green := Pixel[x,y].green * brightness_factor;
  Pixel[x,y].blue := Pixel[x,y].blue * brightness_factor;
end;
It it works, you could replace the mygaussian() function with other possibly better functions.

WojTec 16. Sep 2010 09:21

Re: Vignette effect
 
It's clear all, but not how to implement Gaussian function, I don't understand it too much :cry:

Delphi-Quellcode:
function TwoDimensionalGaussian(X, Y: Single): Single;
var
  a, b, c: Single;
begin

end;
I don't know how to "fill" this function. I'm also not sure parameters and result types, Single are correct? :(

sx2008 17. Sep 2010 23:19

AW: Vignette effect
 
I think the following function is faster and easier to understand
than the gaussian function:

Delphi-Quellcode:
function CalcVignetteBrightness(X, Y: Single): Single;
var
  distance : Single;
  inner_radius, outer_radius : Single;
begin
  inner_radius := 50;
  outer_radius := 150;

  // calculate the distance from the origin (center of the image)
  distance := SQRT(SQR(x) + SQR(Y));
 
  if distance <= inner_radius then
    result := 1.0   // Brightness 100%
  else if distance <= outer_radius then
    // decreasing Brightness from 100% downto 0%
    result := (distance - inner_radius) / (outer_radius - inner_radius)
  else
    result := 0.0; // it's dark outside the outer_radius
end;

WojTec 18. Sep 2010 13:09

Re: Vignette effect
 
This is what I have:

Delphi-Quellcode:
function VignetteBrightness(X, Y: Single): Single;
var
  distance: Single;
  inner_radius, outer_radius: Single;
begin
  inner_radius := 50;
  outer_radius := 150;

  // calculate the distance from the origin (center of the image)
  distance := SQRT(SQR(x) + SQR(Y));

  if distance <= inner_radius then
    result := 1.0 // Brightness 100%
  else if distance <= outer_radius then
    // decreasing Brightness from 100% downto 0%
    result := (distance - inner_radius) / (outer_radius - inner_radius)
  else
    result := 0.0; // it's dark outside the outer_radius
end;

procedure Vignette(ASource: TBitmap32);
var
  Bits: PColor32Entry;
  I, J, XCenter, YCenter: Integer;
  Brightness: Single;
begin
  XCenter := ASource.Width div 2;
  YCenter := ASource.Height div 2;

  Bits := @ASource.Bits[0];

  for J := 0 to ASource.Height - 1 do
  begin
    for I := 0 to ASource.Width - 1 do
    begin
      Brightness := VignetteBrightness(I - XCenter, J - YCenter) * 0.5{=effect depth} + 0.3{basic brightness};

      Bits.R := IntToByte(Round(Bits.R + Brightness));
      Bits.G := IntToByte(Round(Bits.G + Brightness));
      Bits.B := IntToByte(Round(Bits.B + Brightness));

      Inc(Bits);
    end;
  end;

  ASource.Changed;
end;
And no effect - image not changed. Why?
I tried change inner_radius, outer_radius, effect depth and basic brightness, bot no effect too :(

sx2008 18. Sep 2010 13:43

AW: Re: Vignette effect
 
Zitat:

Zitat von WojTec (Beitrag 1050420)
And no effect - image not changed. Why?

You must multiply with the brightness factor.
And you have to care about arithmetic overflow.

Delphi-Quellcode:
function ClampByte(value:Integer):Byte;
begin
  if value > 255 then
    result := 255
  (* not neccesary when a pixel is multiplied with a positive value
  else if value < 0
    result := 0
  *)
  else
    result := Byte(value);
end;
...
Bits.R := ClampByte(Round(Bits.R * Brightness));

WojTec 18. Sep 2010 14:30

Re: Vignette effect
 
Ah, of course, that's my mistake :D
Ok, working, but not exactly as should - darker should be near edges, not center as is now ;)

sx2008 18. Sep 2010 15:19

AW: Re: Vignette effect
 
Zitat:

Zitat von WojTec (Beitrag 1050434)
Ok, working, but not exactly as should - darker should be near edges, not center as is now ;)

Hmm ,there is a little bug:
Delphi-Quellcode:
  else if distance <= outer_radius then
    // decreasing Brightness from 100% downto 0%
//    result := (distance - inner_radius) / (outer_radius - inner_radius) // wrong
    result := (outer_radius - distance) / (outer_radius - inner_radius)


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 Uhr.
Seite 1 von 2  1 2      

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