Live Wallpaper; Background

trebun

Member
Licensed User
Longtime 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

  • stretch_wallpaper.jpg
    stretch_wallpaper.jpg
    92.3 KB · Views: 644
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime 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.
 
Upvote 0

Prosg

Active Member
Licensed User
Longtime 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
 
Upvote 0

Prosg

Active Member
Licensed User
Longtime 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
 
Upvote 0

trebun

Member
Licensed User
Longtime 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:
Upvote 0

Prosg

Active Member
Licensed User
Longtime 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
1.png
 
Last edited:
Upvote 0

trebun

Member
Licensed User
Longtime 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
 
Upvote 0

trebun

Member
Licensed User
Longtime 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...
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime 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
 
Upvote 0

trebun

Member
Licensed User
Longtime 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... ;-)
 
Upvote 0

trebun

Member
Licensed User
Longtime 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...
 
Upvote 0

Prosg

Active Member
Licensed User
Longtime 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
 
Upvote 0

Prosg

Active Member
Licensed User
Longtime 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
 
Upvote 0

trebun

Member
Licensed User
Longtime 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)...
 
Upvote 0
Top