Recent

Author Topic: [Solved] Image Overlap  (Read 2609 times)

zoimutante

  • New Member
  • *
  • Posts: 34
[Solved] Image Overlap
« on: December 31, 2019, 01:26:48 pm »
I need help with overlapping images.
I have two images, the moon, and a "black mask" with alpha channel. I need to the "black mask" overlap the moon image according to a mathematical formula.  What would be the most easy way to perform this ? And the most effective ?

PS: This images are displayed inside a form, if that matter.
« Last Edit: January 05, 2020, 09:37:11 pm by zoimutante »

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
Re: Image Overlap
« Reply #1 on: December 31, 2019, 01:47:41 pm »
Hi, I recommend you BGRABitmap that is cross platform and can be used to draw into a Canvas of a TForm.

In this tutorial is explained the use of masks
https://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5

But if you want to apply a mathematical formula, maybe you need direct pixel access:
https://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_4

Edit: There are also blending modes with BGRABitmap.BlendImageOver for example
« Last Edit: December 31, 2019, 01:53:08 pm by lainz »

zoimutante

  • New Member
  • *
  • Posts: 34
Re: Image Overlap
« Reply #2 on: December 31, 2019, 02:16:08 pm »
Hi, I recommend you BGRABitmap that is cross platform and can be used to draw into a Canvas of a TForm.

In this tutorial is explained the use of masks
https://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5

But if you want to apply a mathematical formula, maybe you need direct pixel access:
https://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_4

Edit: There are also blending modes with BGRABitmap.BlendImageOver for example

Thanks, I think it is exact what I need.  I just don't figure how to install. Download https://github.com/bgrabitmap/bgrabitmap from here and then ? Save it where ? install as a package ?

NM. I found here: https://wiki.freepascal.org/BGRABitmap_tutorial_1 thanks :D

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Image Overlap
« Reply #3 on: December 31, 2019, 05:38:13 pm »
No INSTALL necessary ...
1. Extract to any folder of your choice
2. Tell LAZARUS (Project Options) where to find the files (extra path)

That's it ...  :)
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

circular

  • Hero Member
  • *****
  • Posts: 4217
    • Personal webpage
Re: Image Overlap
« Reply #4 on: January 01, 2020, 05:17:31 pm »
Hmm what kind of formula? Maybe there are some methods that we could suggest depending on what you would like to do.
Conscience is the debugger of the mind

zoimutante

  • New Member
  • *
  • Posts: 34
Re: Image Overlap
« Reply #5 on: January 01, 2020, 05:44:14 pm »
Hmm what kind of formula? Maybe there are some methods that we could suggest depending on what you would like to do.
It will be something like: (current julian calendar day less last know new moon) mod duration of moon cycle in days. The reminder is an approximation of current moon age, then use it to overlap the shadow over the moon picture.
I can't give the right formula now, because I could not find it, but it will be some thing similar, not hard at all. Just an ugly approximation.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Image Overlap
« Reply #6 on: January 01, 2020, 06:11:42 pm »
Hi!

If found that in my sources:

Code: Pascal  [Select][+][-]
  1. //========== MoonPhase =================
  2. // 0 :           Vollmond          full moon
  3. // 0..0.5 :      Abnehmender Mond  waning moon
  4. // 0.25 :        Halbmond          half moon -
  5. // 0.5 :         Neumond           new moon
  6. // 0.75 :        Halbmond          half moon  +
  7. // 0.5..0.9999:  Zunehmender Mond  waxing moon
  8. // goto Vollmond
  9. function MoonPhase(DT: TDateTime) : single; //  DT must be UTC!!!
  10. // synodischer Mondumlauf im Mittel= Lunation; ± 0.25 days (!!!!) Moon is wobbling!
  11. const syn = 29.530589;
  12. var Fullmoon: TDateTime;
  13.     phase : Single;
  14. begin
  15. // Vollmond Sonntag, 3. Dezember 2017, 15:46:59 Uhr UTC
  16. FullMoon := EncodeDate(2017,12,3) + EncodeTime(15,46,59,0);
  17. phase := (DT-FullMoon)/syn;
  18. result := frac(Phase);
  19. end;
  20.  

But: The moon is wobbling. With this linear interpolation  you can be a lot of degrees away from the real position.

To get the (amateur) position of the moon with +/- 1 degree, you need around 20 formulas!

Winni

« Last Edit: January 01, 2020, 06:16:48 pm by winni »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Image Overlap
« Reply #7 on: January 01, 2020, 06:55:21 pm »
But: The moon is wobbling. With this linear interpolation  you can be a lot of degrees away from the real position.

You aren't calculating the Moon position but its phase. A still approximate but more correct calculation is:

Code: Pascal  [Select][+][-]
  1. {
  2.  Determines APPROXIMATE phase of the moon (percentage lit)
  3.  0.00 = New moon, 1.00 = Full moon
  4.  Due to rounding, full values may possibly never be reached
  5.  Valid from Oct. 15, 1582 to Feb. 28, 4000
  6.  Calculations and BASIC program found in
  7.    "119 Practical Programs For The TRS-80 Pocket Computer"
  8.    by John Clark Craig, TAB Books, 1982
  9.  Conversion to Turbo Pascal by Alan Graff, Wheelersburg, OH
  10.  Further adapted by Luis Caballero, Madrid, Spain
  11. }
  12. function TMainForm.MoonPercentLit(const Julian: Integer): Double;
  13. var
  14.   m:real;
  15. begin
  16.   m := (Julian + 4.867) / 29.53058;
  17.   m := 2 * (m - Int(m)) - 1;
  18.   Result := Abs(m) * 100;
  19. end;

with Julian calculated as:

Code: Pascal  [Select][+][-]
  1. {var ADate: TDateTime}
  2. ADate := EncodeDate(yy, mm, dd);
  3. Julian := Trunc(DateTimeToJulianDate(ADate)) + 1;
« Last Edit: January 01, 2020, 06:57:44 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Image Overlap
« Reply #8 on: January 01, 2020, 07:05:16 pm »
Hi!

The way you do it and i do it is a rough simplification:

A linear relation between time and phase.
If you want the days from my formula then it is only the obvious line missing:

Days := MoonPhase * syn;
or
Date :=  MoonPhase * syn OffsetDate;

My stuff has the advantage that it works with Dephi dates - no conversion needed.
The disadvantage is - due to Delphi TDateTime implementation - that it is only valid for Dates >1.1.1900.

Winni


circular

  • Hero Member
  • *****
  • Posts: 4217
    • Personal webpage
Re: Image Overlap
« Reply #9 on: January 01, 2020, 07:10:46 pm »
It will be something like: (current julian calendar day less last know new moon) mod duration of moon cycle in days. The reminder is an approximation of current moon age, then use it to overlap the shadow over the moon picture.
Ok so it is about the position of the mask.
Conscience is the debugger of the mind

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Image Overlap
« Reply #10 on: January 01, 2020, 07:23:43 pm »
Hi!

Now I found it : drawing the moon phases.

Parameter phase is the moonphase as shown in the last post.


Code: Pascal  [Select][+][-]
  1. // img must be square!
  2. procedure DrawMoon (Img: TImage; Phase : single);
  3. var
  4. radius,MidXY: Integer;
  5. p1,p2,p3,p4 : TPointF;
  6. tmp : TBGRABitMap;
  7. Xpos, YPos, Rpos, Xpos1, Xpos2, Percent: single;
  8. R : Trect;
  9. sign : String;
  10. begin
  11. tmp  := TBGRABitmap.create(Img.Width,Img.Height,cssBlack);
  12. MidXY :=  Img.width div 2;
  13. radius := MidXY - 4;
  14. // Ganzer Mond in Blau
  15. tmp.FillEllipseAntialias(MidXY,MidXY,radius,radius,CssBlue);
  16. tmp.EllipseAntialias(MidXY, MidXY,radius,radius,CssYellow,0.5);
  17. tmp.LineCap := pecRound;
  18. Ypos := 0.0;
  19. // Gelben Teil des Mondes zeichnen - yellow part of moon
  20. while YPos <= radius do
  21.    begin
  22.    Xpos := Sqrt (sqr(radius) - sqr(Ypos));
  23.    RPos := 2*Xpos;
  24.     if Phase < 0.5 then  // abnehmed
  25.         begin
  26.           Xpos1 := -Xpos;
  27.           XPos2 := Rpos-2*Phase*Rpos-Xpos;
  28.         end else        // zunehmend
  29.         begin
  30.           XPos1 := +XPos;
  31.           XPos2 := Rpos-2*Phase*Rpos+Xpos;
  32.         end;
  33.     p1 := PointF (Xpos1+MidXY, MidXY-Ypos);
  34.     p2 := PointF (XPos2+MidXY, MidXY-Ypos);
  35.     p3 := PointF (XPos1+MidXY, MidXY+YPos);
  36.     p4 := PointF (XPos2+MidXY, MidXY+YPos);
  37.  
  38.     tmp.DrawLineAntialias(p1.x,p1.y,p2.x,p2.y,cssYellow,1);
  39.     tmp.DrawLineAntialias(p3.x,p3.y,p4.x,p4.y,cssYellow,1);
  40.     yPos := yPos + 0.5;
  41.    end;// Ypos
  42.  
  43. R := Rect (0,0,Img.Width,Img.Height);
  44. Img.Canvas.CopyRect(R,tmp.Canvas,R);
  45. tmp.free;
  46.  
  47. if phase > 0.5 then sign := '[+]' else sign := '[-]';
  48. if phase > 0.5 then Percent := 1.0 - phase else Percent := phase;
  49. Percent := 100 -Percent * 100 *2;
  50. Img.Hint := 'Moon '+ intToStr(round(Percent))+'% '+sign;
  51. end;
  52.  
  53.  
  54.  

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Image Overlap
« Reply #11 on: January 02, 2020, 01:42:32 am »
Here is a screenshot of the code above.

Winni

 

TinyPortal © 2005-2018