### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [Solved] Image Overlap  (Read 1305 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: 3918
• Leandro Diaz
##### 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

#### RAW

• Hero Member
• Posts: 867
##### 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) And Windows XP Pro (x86 Sp3) - LAZARUS 2.0.8 FPC 3.0.4 - TRUNK 2.1.0 FPC 3.3.1
// This is polarity (hell) and hell is reigned by lies, nothing but lies. Be careful what you believe ...
// There are 10 types of people in this world, those who understand mind control and ...

#### circular

• Hero Member
• Posts: 3645
##### 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: 2116
##### 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: 3428
##### 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
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][+][-]
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 !!!)
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

#### winni

• Hero Member
• Posts: 2116
##### 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: 3645
##### 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.
Conscience is the debugger of the mind

#### winni

• Hero Member
• Posts: 2116
##### 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
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
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: 2116
##### Re: Image Overlap
« Reply #11 on: January 02, 2020, 01:42:32 am »
Here is a screenshot of the code above.

Winni