ImageLibEx library

pdabasic

Active Member
Licensed User
I try to use the slideshow function like an background effect but after the effect the transparency labels aren't transparent :sign0085:
And the effect is very slow in my emulator :(
How can I do it faster?

Here is my code:

B4X:
Public Sub formFadeShow (ParentForm,TargetForm)
   FadedForm = "Main."&TargetForm
   imgTargetBg = "Main.img"&TargetForm&"Bg"
   CapFade.New1
   CapFade.ControlCapture("Main."&ParentForm,0,0,240,320)
   Control(imgTargetBg,Image).Image = CapFade.Image
   imgCapture.Image = CapFade.Image
   BmExFade1.New3(imgCapture.Image)
   BmExFade2.New2(imgFadeBg.Width,imgFadeBg.Height)
   DrawExFade.New2(BmExFade2.Value)
   DrawExFade.Clear(cBlack)
   ShowFade.New1
   ShowFade.NewTransition(BmExFade1.Value,BmExFade2.Value,cGray,True)
   timFadeIn.Interval = Interval
   timFadeIn.Enabled = True
   Control("Main."&TargetForm,Form).Show
End Sub

Sub timFadeIn_Tick
   Percent = Percent + Increment
   Control(imgTargetBg,Image).Image = ShowFade.Fade(Percent)
   If Percent >= FadeContrast Then
      timFadeIn.Enabled = False
      Percent = 0
   End If
End Sub

And the result:
 

Attachments

  • ScreenShot.jpg
    ScreenShot.jpg
    14.5 KB · Views: 25

agraham

Expert
Licensed User
Longtime User
If by emulator you mean the Microsoft device emulator running on the desktop then yes, it is slow and no, you can't get it to go faster.

You should be calling EndTransition after the fade has finished.

I am not entirely certain what your controls and objects are. It is always best to post a small sbp file that will run so we can see the problem. Otherwise we just waste time trying to guess what you are doing.

In this case my guess is that "Main.img"&TargetForm&"Bg" is an Image control and things don't work the way you think. A transparent label draws itself using the image of the form or panel on which it is located. remove the image control and try setting Form.Image with the fade. I don't know if that will work, if you had posted a demo of the problem I would probably have tried a quick mod to test it but I'm not going to waste time trying to re-implement what I think you are doing. :(
 

klaus

Expert
Licensed User
Longtime User
Concerning AutoScale.
I had the feeling, on my htc Touch HD, for quite some time, that the refreshing of the screen with AutoScale and the ImageLibEx is very slow on a Form's forelayer, but had never made any comparisons yet. But now this has been done.

Attached several source codes showing the problem:
- TestMouseMove with
drwMainF.RefreshForm2("frmMain",rectDest.Value)
very slow
- TestMouseMove1 with frmMain.Refresh faster but still slow
- TestMouseMoveVGA, true Vga, with frmMain.Refresh, much faster !

I'm about thinking that I will abandon using AutoScale, directly program for VGA, and change the dimensions of the controls and fonts to QVGA.
This question is also open for the future, would the standard screen size be VGA and have an AutoScale for 'older' QVGA screens, or still remain with the standard QVGA screen and AutoScale to VGA ?

There is also a 'strange' need for the destination rectangle definition with AutoScale for the device if the x and y coordinates are different to ZERO.
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]rectDest.New1(ScreenX0,ScreenY0,ScreenX0+ScreenW*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenY0+ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[/SIZE][/FONT]
and not
B4X:
[SIZE=2][FONT=Courier New][SIZE=2][FONT=Courier New]rectDest.New1(ScreenX0,ScreenY0,ScreenW*[/FONT][/SIZE][/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[/SIZE][/FONT]

I hope that the explanations a clear !?

Best regards.
 

Attachments

  • TestMouseMove.sbp
    3.2 KB · Views: 8
  • TestMouseMove1.sbp
    3.2 KB · Views: 7
  • TestMouseMoveVGA.sbp
    2.8 KB · Views: 6
Last edited:

agraham

Expert
Licensed User
Longtime User
I am a bit surprised that there is a difference between DrawerEx.RefreshForm2 and Form.Refresh as they both do much the same thing, they mark an area of the form invalid and so force a repaint of the form. It is the repainting of the Form that takes the time, not the invalidation. None of the methods in ImageLibEx do any extra work when AutoScaled so the performance hit is not in the library. It may be that callling Refresh on the form forces an immediate call directly to repaint whereas invalidating and then repainting an area may have to go via messages to the application message loop and so may be actually be slower - but I don't know about those internal implementation details. I would just use whatever is fastest :)

An AutoScaled Form still has QVGA sized bitmaps internally and on a repaint they are stretched to fit the VGA screen making the VGA image a bit "fuzzy". I guess this stretching is where the performance penalty over true VGA is.

Have you tried NativeImage and NativeFormImage from the ControlsExDevice library with AutoScale? They should give you the benefits of AutoScaling the controls but let you control the graphics yourself. I would expect their performance to be the same whether AutoScaled or not. In this case using Form.Refresh avoids some confusion over the area to invalidate (described in the help) and as you noted may even be faster.

There is also a 'strange' need for the destination rectangle definition with AutoScale for the device if the x and y coordinates are different to ZERO.
Are you referring to the use of the Rectangle in RefreshForm2? As I said above ImageLibEx does no AutoScale processing so the invalidated area is defined in screen co-ordinates not in notional QVGA co-ordinates. I would however expect to use -

B4X:
rectDest.New1(ScreenX0*ScreenScaleX, ScreenY0*ScreenScaleY, ScreenW*ScreenScaleX, ScreenH*ScreenScaleY)
Your code includes an unnecessary area to top and left of the required rectangle - but as Form.Refresh seems quicker perhaps this is an academic point.
 

klaus

Expert
Licensed User
Longtime User
Coming back to the rectangle definition.
For copying a partial image on the screen.
When running the attached program, on the device AutoScale compiled, the graphic is not at the right place with:
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]rectDest.New1(ScreenX0, ScreenY0, ScreenW*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2], ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[SIZE=2][FONT=Courier New]rectSrc.New1([/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenW*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT][/SIZE][/FONT]
clicking on the Rect button sets:
B4X:
[FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]rectDest.New1(ScreenX0, ScreenY0, ScreenX0+ScreenW*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2], ScreenY0+ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[SIZE=2][FONT=Courier New]rectSrc.New1([/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenX0+ScreenW*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleX[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2],ScreenY0+ScreenH*[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]ScreenScaleY[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2])[/SIZE][/FONT]
[/SIZE][/FONT]
and the graphic is on it's right place.

The same happened with the Refresh function and the rectangle in the TestMouseMove program.

I have not yet tried the NativeImage object, will do it quite soon.

Best regards.
 

Attachments

  • TestMouseMove_N.sbp
    5.7 KB · Views: 7

agraham

Expert
Licensed User
Longtime User
I am afraid that you are confusing things by using the same Rectangle for drawing as for refreshing. Replace all the drwMain.RefreshForm2 with frmMain.Refresh and remove all the ScreenScaleX and ScreenScaleY scaling from rectDest and you will find it works fine when AutoScaled. The drawing rectangle needs to be specified in QVGA co-ordinates because it is drawing on a QVGA sized bitmap in the form - this is the whole point of AutoScale, it uses QVGA co-ordinates. The refresh rectangle needs to be specified in physical screen co-ordinates because it needs to invalidate the actual area drawn on the screen.

So if you have a drawing rectangle

rectDest.New1(ScreenX0, ScreenY0, ScreenW, ScreenH)

you need a refresh rectangle

rectRefresh.New1(ScreenX0*ScreenScaleX, ScreenY0*ScreenScaleY, ScreenW*ScreenScaleX, ScreenH*ScreenScaleY)

or just use Form.Refresh.
 

ceaser

Active Member
Licensed User
Hi Agraham

Thanks for a wonderful and powerful library. I have rewritten my CAD program using your library and will post it soon on the forum.

Just one thing. Is it please possile to add a function to draw an arc by defining three points on the arc? How about defining one's own line types i.e. a fenceline, etc.

Regards
Michael
 

agraham

Expert
Licensed User
Longtime User
Just one thing. Is it please possile to add a function to draw an arc by defining three points on the arc
If you can give me an algorithm I'll look at it.
How about defining one's own line types i.e. a fenceline, etc.
I've no idea what a fenceline is but look at DrawerEx.DrawLineDashDot.
 

sitajony

Active Member
Licensed User
Hi, I used AlphaBlend() in coredll but it return an image with a black border so I would try with this library but I don't understand how use it? It return always an error like "Exception", "NotImplemented..." Is right that we can finally draw an image correctly with the Alpha value from a PNG Image on an image? If yes how do it?
Thanks for your replies!
 

agraham

Expert
Licensed User
Longtime User
Are you trying so use ReadAlphaData on a device? From a comment in the ImageAlpha.sbp demo

' make the alpha data file on the desktop, throws a NotImplemented exception on the device

That demo shows you how to do it. The alpha data file must be made on the desktop as devices can't read alpha values in png files.
 

sitajony

Active Member
Licensed User
But how do by example W**bar Ad*ance Des*top and some others softwares? There's surely an other soluce to get the alpha value... I'm searching...
 

sitajony

Active Member
Licensed User
I found how get the alpha value... In fact I use OpenNETCF and it works great...
This is an example with transparency by pixel and transparency by Alpha value:
attachment.php

It's a really better...
Not computer needed, just type withalpha((Bitmap) Support, (String) Image File, (Int) X, (Int) Y, (Int) Width, (Int) Height) and it return the pasted image with the gif/png...
Hum I don't know if I can post my lib coz it's not really my lib, I use an other API (in OpenNETCF) so I don't know...
 

Attachments

  • capture1.jpg
    capture1.jpg
    14.3 KB · Views: 131

agraham

Expert
Licensed User
Longtime User
Version 2.2 now posted includes an additional DrawerEx method. DrawArc3 takes three points, calculates the centre and radius of the circle that encloses all three points and draws the arc of that circle that connects those three points. Some parts of the algorithm used bear a remarkable :) similarity to that in a Basic4ppc program previously posted by Klaus who also supplied the raw equations to implement.
 

klaus

Expert
Licensed User
Longtime User
Ai Andrew,

I have noticed that with the RotateHQ function there are pixels that don't have the right fillcolor.

The attached program and the pictures below show the problem.

This doesn't happen with the RotateFast function.

Could you please have a look at it.

Thank you in advance and Best regards.
 

Attachments

  • RotateNeedle.zip
    17 KB · Views: 12
  • RotateHQ.jpg
    RotateHQ.jpg
    15.9 KB · Views: 20
  • RotateFast.jpg
    RotateFast.jpg
    15.9 KB · Views: 21

agraham

Expert
Licensed User
Longtime User
It's a transparency issue. Because RotateHQ achieves the higher quality by a weighted interpolation of the colours of the four original pixels that cover the block where the rotated pixel is to be positioned and because the colour values are integers and the weighting factors are not there will be a final rounding effect on the final colour value. In this case that is varying the needle background colour from the transparent value that you are using.

In this case you could minimise the effect by chopping off the white extension to the needle on the bitmap and calulating an appropriate x and y offset to position the rotated needle at the centre of the dial. Using a less obvious transparent colour, such as mid-grey, might also be beneficial.
 
Top