Live Wallpaper; Background

trebun

Member
Licensed User
Hi,

I need help to scale the background images for my live wallpaper.

I take a random flyer from my site with the url:

>> http://.../electronic/fcDownload.php (only some test flyer available)

In the attachments, I uploaded my project (construction area - haha! - not all will work correctly. If all things are done, I will upload and share the code in "Basic4android Share Your Creations"! Promise!)

In the WallpaperService I need to scale the backgroundimage with the right ratio. I need this dynamicly, because not all flyer have the same scaling.

B4X:
Sub LWM_OffsetChanged (Engine As LWEngine)
      
   If Flyer.IsInitialized  Then
      
      Engine.Rect.Left = -Engine.CurrentOffsetX 
      Engine.Rect.Top = -Engine.CurrentOffsetY 
      Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth 
      Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
      
      Engine.Canvas.DrawBitmap(Flyer, Null, Engine.Rect)

   Else
      Engine.Canvas.DrawColor(Colors.Black)
      Engine.Canvas.DrawText(AResMap.Get("other_placeholder_on_screen"), 120dip, 120dip, Typeface.DEFAULT_BOLD, 30, Colors.White, "LEFT")
   End If
   
   Engine.RefreshAll
End Sub
This works good, but all images on my GNex or N7 are clinched. I think it is a problem with "FullWallpaperHeight" (=1280). But on both devices, I have software buttons they must be subtracted from the "FullWallpaperHeight".

I test it with
B4X:
pScreenHeight=GetDeviceLayoutValues.Height
pScreenWidth=GetDeviceLayoutValues.Width
But I have no Idea with the nice offset x/y. So, please :sign0085:

Regards,
trebun
 

Attachments

Last edited:

Erel

Administrator
Staff member
Licensed User
See this code:
B4X:
Sub Process_Globals
   Dim imageName As String : imageName = "tempImage"
   Dim lwm As LWManager
   Dim LiveEngine As LWEngine
   Dim image, resized As Bitmap
End Sub
Sub Service_Create
   lwm.Initialize("lwm", False)
   image = LoadBitmap(File.DirAssets, "rescue.jpg")
End Sub

Sub Service_Start (StartingIntent As Intent)

End Sub

Sub Service_Destroy

End Sub

Sub ResizeImage(original As Bitmap, TargetX As Int, TargetY As Int) As Bitmap
   Dim origRatio As Float = original.Width / original.Height
   Dim targetRatio As Float = TargetX / TargetY
   Dim scale As Float
   
   If targetRatio > origRatio Then
      scale = TargetY / original.Height
   Else
      scale = TargetX / original.Width
   End If
   
   Dim c As Canvas
   Dim b As Bitmap
   b.InitializeMutable(TargetX, TargetY)
   c.Initialize2(b)
   'set the background
   c.DrawColor(Colors.LightGray)
   Dim r As Rect
   Dim w = original.Width * scale, h = original.Height * scale As Int
   r.Initialize(TargetX / 2 - w / 2, TargetY / 2 - h / 2, TargetX / 2 + w / 2, TargetY / 2+ h / 2)
   c.DrawBitmap(original, Null, r)
   Return b
End Sub

Sub LWM_OffsetChanged (Engine As LWEngine)
   If image.IsInitialized AND resized.IsInitialized = False Then
      resized = ResizeImage(image, Engine.FullWallpaperWidth, Engine.FullWallpaperHeight)
   End If
   If resized.IsInitialized Then
      Engine.Rect.Left = -Engine.CurrentOffsetX
      Engine.Rect.Top = -Engine.CurrentOffsetY
      Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
      Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
      Engine.Canvas.DrawBitmap(resized, Null, Engine.Rect)
   End If
   Engine.RefreshAll
End Sub
The important part is ResizeImage. This method will rescale the original image without changing its original ratio.
 

trebun

Member
Licensed User
Erel,

I can't wait to go home and try you solution.

:sign0188:

THANK YOU!

Regards,
trebun
 

Prosg

Active Member
Licensed User
i try it and the scale work perfectly :)

Thx a lot erel

only a small bug :

if we change the image with :
B4X:
CallSub(WallpaperService, "ImageChanged")
it doesn't change. i think it's because of resized.IsInitialized
The resized must be off i think

B4X:
Sub ImageChanged
   If File.Exists(File.DirInternal, imageName) Then
      image = LoadBitmap(File.DirInternal, imageName)
      If LiveEngine.IsInitialized Then LWM_OffsetChanged(LiveEngine)
   End If
End Sub
B4X:
Sub LWM_OffsetChanged (Engine As LWEngine)
    If image.IsInitialized AND resized.IsInitialized = False Then
        resized = ResizeImage(image, Engine.FullWallpaperWidth, Engine.FullWallpaperHeight)
    End If
    If resized.IsInitialized Then
        Engine.Rect.Left = -Engine.CurrentOffsetX
        Engine.Rect.Top = -Engine.CurrentOffsetY
        Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
        Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
        Engine.Canvas.DrawBitmap(resized, Null, Engine.Rect)
    End If
    Engine.RefreshAll
End Sub
 

Prosg

Active Member
Licensed User
This resolve my problem

B4X:
Sub LWM_OffsetChanged (Engine As LWEngine)
    If image.IsInitialized Then
    image = ResizeImage(image, Engine.FullWallpaperWidth, Engine.FullWallpaperHeight)
        Engine.Rect.Left = -Engine.CurrentOffsetX
        Engine.Rect.Top = -Engine.CurrentOffsetY
        Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
        Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
        Engine.Canvas.DrawBitmap(image, Null, Engine.Rect)
    End If
    Engine.RefreshAll
End Sub
 

trebun

Member
Licensed User
Erel, this solution is awesome - the flyer looks really clear!

I hope my last question: Is it posible to make a static background as "Live Wallpaper"? I mean to disable the background-scolling-method (in back of the head that must work on different launcher)...

I found this code:
https://github.com/kghost/android-s...st/android/static_live_wallpaper/Service.java

Maybe this point (my naive approach)?

B4X:
@Override            
public void onReceive(Context context, Intent intent) {         
draw();
}
But is it possible to adapt this into B4A?

Regards,
trebun
 
Last edited:

Prosg

Active Member
Licensed User
trebun do you have test the resized in a 320 x 480 mdpi ?

For me the resized is not very good and you ?

1.png is in 320x480
 
Last edited:

trebun

Member
Licensed User
The offset_changed event actually implements the scrolling. You can remove it (or always draw the same image relatively to 0, 0 instead of CurrentOffsetX, Y.
OK, it works - I delete [...]Offset_Changed.

But, If I have two or more screens, the flyer will not redraw correctly.

Preview: http://s14.directupload.net/images/130108/zsfh6ema.jpg

Coding:

JobDone (after Job.Success = True), I use HTTPUtils2
B4X:
[...]
If LWE.IsInitialized Then DrawTheF___ingPicture(LWE)
[...]
B4X:
Sub DrawTheF___ingPicture (Engine As LWEngine)

    If Flyer.IsInitialized = True AND Resized.IsInitialized = False Then
        Resized = ResizeImage(Flyer, Engine.FullWallpaperWidth, Engine.FullWallpaperHeight)
    End If
    If Resized.IsInitialized Then
        Engine.Rect.Left = -Engine.CurrentOffsetX
        Engine.Rect.Top = -Engine.CurrentOffsetY
        Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
        Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
        Engine.Canvas.DrawBitmap(Resized, Null, Engine.Rect)
    End If
    Engine.RefreshAll      

End Sub
I play with -Engine.CurrentOffsetX,Y, set to 0 and so on - awful effects... :/

I know, I'm a bad guy to ask some kindergarten questions, buuuut... :sign0085:

Maybe is here a guy with a heart of gold to write a tiny tutorial about the Offset X,Y...?

Regards,
trebun
 

trebun

Member
Licensed User
Have you tried:
B4X:
If Resized.IsInitialized Then
        Engine.Rect.Left = 0
        Engine.Rect.Top = 0
        Engine.Rect.Right = 0 + Engine.FullWallpaperWidth
        Engine.Rect.Bottom = 0 + Engine.FullWallpaperHeight
        Engine.Canvas.DrawBitmap(Resized, Null, Engine.Rect)
    End If
Exact! But it doesn't work - I'm not at home to test it again, what the effect is. I mean, the position of the image was wrong, but scrolling and redraw was fine. Only the image was not on the proper position...
 

Erel

Administrator
Staff member
Licensed User
Add a process global variable named actualImageWidth.
Set its value in ResizeImage sub:
B4X:
   Dim w = original.Width * scale, h = original.Height * scale As Int
   actualImageWidth = w
B4X:
Sub LWM_OffsetChanged (Engine As LWEngine)
   If image.IsInitialized AND resized.IsInitialized = False Then
      resized = ResizeImage(image, Engine.FullWallpaperWidth, Engine.FullWallpaperHeight)
   End If
   If resized.IsInitialized Then
'      Engine.Rect.Left = -Engine.CurrentOffsetX
'      Engine.Rect.Top = -Engine.CurrentOffsetY
'      Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
'      Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
      Engine.Rect.Left = -(Engine.FullWallpaperWidth - actualImageWidth) / 2
      Engine.Rect.Top = 0
      Engine.Rect.Right = Engine.Rect.Left + Engine.FullWallpaperWidth
      Engine.Rect.Bottom = Engine.FullWallpaperHeight
      Engine.Canvas.DrawBitmap(resized, Null, Engine.Rect)
   End If
   Engine.RefreshAll
End Sub
 

trebun

Member
Licensed User
@Fili,

you will exact the same thing - download a picture from a webserver and view as background (live wallpaper) without scrolling.

Erel is helping me with the sizing and position of the image - see all posts here - I think a solution is here... ;-)
 

trebun

Member
Licensed User
ok it's Working

Great Erel thx a lot :)
Great!

I give up! I think it is for me not possible to make a static wallpaper... :-(

http://s14.directupload.net/images/130109/eqj4o38b.jpg

In portrait everthing is fine (background is not in the middle, but who cares?), switch to Landscape and the Image is not change or redraw - but it looks like complicated because I need to rescale it.

I don't see the landscape problem before, because I deactivated this option in my launcher...
 

Prosg

Active Member
Licensed User
Are u sure your emulateur is real 1280 ? you can see the exact device detail in the designer click connect and bottom right

sometime you think your device is 1280 and it's not
 

Prosg

Active Member
Licensed User
There is realy realy no way to make is automaticly ?

B4X:
Sub APIlevel As Int 
    Dim r As Reflector
    Return r.GetStaticField("android.os.Build$VERSION", "SDK_INT")
End Sub
Sub LWPselector 
    Dim Intent1 As Intent
    Intent1.Initialize(Intent1.ACTION_MAIN, "")
    If APIlevel<15 Then
        Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperListActivity")
    Else
        Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperActivity")'this will work for android 4.0.4
    End If
    StartActivity(Intent1)
End Sub
 

trebun

Member
Licensed User
Are u sure your emulateur is real 1280 ? you can see the exact device detail in the designer click connect and bottom right

sometime you think your device is 1280 and it's not
I dont work with the Emulator - I use my hardware devices (Galaxy Nexus, Nexus7)...
 
Top