Android Question Loadbitmap works fine debug mode but not in release

Melchor99

Member
Licensed User
Longtime User
Hi,

For a little game based on a timer, I'm loading a PNG into an imageview

ImageFondo.Bitmap = LoadBitmapSample (File.DirAssets, "roadholland.png")
15144 x 800 (96kb) not to heavy

To simulate speed, I move the image on timer ticks:

ImageFondo.Left = ImageFondo.Left - x

All is working fine in debug mode in my old AVD 2.2 API 8 ARM (armeabi) virtual device

But after generating the apk in release mode and try it on my phone, all game works except ImageFondo which appears completely black, so I can't see the road :(

Please, could you try to guide me about how to solve this issue? Virtual device works fine, but apk on my modern phone turns black the image of the road or it does not load it, no exception is shown.

Thanks & Regards
 
Last edited:

sorex

Expert
Licensed User
Longtime User
the image is not heavy in file size but it is in dimensions.

wasn't it limited to maximum 2048 or something in the old android versions?

try to reduce it with loadbitmapresize to the exact resolution you need.

by the way why is it 15144px wide?
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
thanks for quick response,

I'm not aware of the limitation of 2048, the fact is that in debug mode all is working fine, behaviour, images, all run properly

Reason of 15144px wide is that I have created a road in my game with different scenarios, day, night, mountain, sea etc.. and cars movement by timer run across all this scenario contained in the png

In my game player is fixed in middle of the screen and rivals and scenario move to generate the speed feeling instead of it.

Progress by the cars across the road (png) is generated by command:

ImageFondo.Left = ImageFondo.Left - x

I think that if the issue is a posible limitation of 2048px it shouldn't work in debug mode but it does :(, the problem is the apk in a mobile once generated in reléase mode
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
From my experience that sounds like it is far too big an image for Android to handle.

It might be working in debug mode because in non-legacy debug mode a lot of the work is actually being performed in Java on the desktop, which can handle handle larger images, while only the UI is being run on the device. If this is so then it will probably not work in legacy debug mode where it all happens on the device.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The image is loaded in all cases on the device.
The difference is probably related to the virtual assets folder which is a regular folder unlike in release mode where the file is loaded directly from the APK.

As written above the file size is meaningless. Only the image dimensions matter and trying to load a 15000 wide image is a mistake. You should instead load a downsampled image.
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
also split the image into seperate files (day, night, mountain etc) and load them when needed or preload them.
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Thanks for your responses,

Let me take some time to check options, yesterday night I started splitting images and load them when left axis reaches the maximum siez of one of them to show the next image, but I have no time to check if it works yet.

I will try solutions provided in this thread and share results. Thanks a lot.

Regards
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Hi,

yesterday I tried different possible solutions based on your advices.

I tried ScaleImageView and set the control properly but after trying some times to load the image it appears in reduced size in control, tried different zooms and parameters but I didnt' get the point to set it properly.

In API19 - Android 4.4 virtual device I get a downsampling message in log and the image appears was distorted (Imageview control with loadbitmap 15144px x 800px (96kb)

I tried to include in main attribute the heap parameter which is mentioned in other posts.

Finally, I took the decission to split image, I tested 10.000x800 (not working), 7.500x800(works), 5000x800 works. Now I'll prepare the code to define transitions between images

Thanks & Regards
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
the idea of operation/implementation is still bad.

why don't you try to create a tile based mapping routine?

then the maximum size of image(s) is limited to your screen size or a bit beyond that.

I wonder how you will test collisions with just 1 big image that you move around.
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Hi,

For this project I won't consider colisions, with .top I will make that player can't move out of the road only, then, the game is based on increases/decreases of speed to beat a big number of rivals with different random events as stamina, energy consumption etc.. which affects the speed of players and rivals.

Final solution has been:

In active_create event I loaded the three parts of the road:

B4X:
    imagefondo.Bitmap = LoadBitmap (File.DirAssets, "road/roadholland_1_0_7499.png")
    imagefondo.left = 0dip
    imagefondo.top = 0dip
    imagefondo.width = 4850dip
    imagefondo.Height = 450dip
  
    imagefondo2.Bitmap = LoadBitmap (File.DirAssets, "road/roadholland_2_7500_14999.png")
    imagefondo2.left = 4850dip
    imagefondo2.top = 0dip
    imagefondo2.width = 4850dip
    imagefondo2.Height = 450dip
  
    imagefondo3.Bitmap = LoadBitmap (File.DirAssets, "road/roadholland_3_15000_22499.png")
    imagefondo3.left = 9700dip
    imagefondo3.top = 0dip
    imagefondo3.width = 4850dip
    imagefondo3.Height = 450dip

On timer tick:

B4X:
    ImageVehicle.Left = ImageVehicle.Left + 2dip
  
    imagefondo.Left = imagefondo.Left - 2dip
    imagefondo2.Left = imagefondo2.Left - 2dip
    imagefondo3.Left = imagefondo3.Left - 2dip

I found two issues doing this, Please, if someone can guide me about how to solve:

(1) I have establish 4850dip in imagefondo,imagefondo2,imagefondo3 to fit with 7499px parts with test and error method in avd device but it's not still exact :(. How can I set the exact measure in dips to fit with 7499px?

(2) Testing in an avd with 3,7 inches all is working fine, but same apk in my real device of 5,5 inches, vehicle finish exactly at the middle of the road when timer_tick changes to enable=false. I mean distance that vehicle completes in 5'5inch real device is exactly the half than it does in 3,7inchs avd device. I have tried different ways to solve it but I'm not sure why happens :(

Two points to consider:
- In Activity script I've set:
AutoScaleAll
- All images (imagefondo,imagefondo2,imagefondo3 and imagevehicle) are contained in a Panel in the activity not directly in the activity form)

Thanks & Regards
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Please use code tags when posting code.
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
don't use autoscale and use your own math based on the width and height of the current screen.

your 2dip would be 100%x*.01 or something and if it's <1 you take 1 to prevent freezes due to following int values.

what is the reason for the player +2dip when you say that the player remains in the middle of the screen?
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Player in the presentation of the game screen advance until 120dip which is the center of the screen, during the game it does not move from the center, and when it arrives to the finish line it progress +2dip until the end of the screen to finish the game
All ítems (players and rivals) have a field in type structure which contain the distance covered in dips
In my previous post I've written ImageVehicle.Left = ImageVehicle.Left + 2dip as representative of the rivals (not the player), you are right, player does not move from the center of the screen but I think it shouldn't have influence in the distance, but I'm a bit confused so perhaps it could affect in some way

Ill try to check your solution managing Autoscale parameter and come back with results. Thanks a lot!
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Hi,

I'm near the final solution, currently, in both devices (avd 3'7) and real device 5'5, vehicle end line happens in the same pixel point.

100km of my game are 6664dip. I have set some labels temporaly in the panel as debug information getting:

- Avd 3,7: 6664dip for 100km of game = 9996px (seems a ratio of 1,5)
- Real Device 5,5: 6664dip for 100km of game = 19992px (seems a ratio of 3)

Now I have to made last adjustment to show km of the game in the screen during the race, which will be: Temporal_distance_completed (in px transformed from dip) * 100 / 6664dip which are 100km

After removing AutoScaleAll, screen shows in small size in 5,5 real device, so I will have to resize in dips main Panel of the game

Thanks & Regards
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
yes, that's what I wrote 2 days ago.

scale the image based on the screen height.

something like

B4X:
Dim oW,oH,nW,nH As Int
Dim r As Float
oW=4850 'original image width
oH=300 'original image height
r=oW/oH
nH=100%y
nW=nH*r
Log(nW &" "& nH)
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Hi,

Finally I solved issues related to pixels scenary and rotation, currently my development moves 50 vehicles with a timer considering coordinates of the player which is in the center in the screen, main core of the game is completed but I have one last issue.

Timer is set to 1/10 second and has some events, to check position, distance covered, sum distance, time, check if someone has arrive to the end of the road etc.. for all the 50 vehicles (array of a new type created by me with info required)

In addition timer makes two loadbitmaps commands for each vehicle because each vehicle has two sprites.

I'm experiencing some slowness in timer I think due to this load of instructions. I have use threads in a previous project but in this game I don't to use it because I want to manage same array of information of each vehicle with only the timer

Please, some could guide me about how to improve performance in timer, loadbitmap or any other concept that I can consider?

Thanks & Regards
 
Upvote 0

udg

Expert
Licensed User
Longtime User
I guess that part of the instructions don't need to be executed every 1/10th of second. So you could use a counter and execute those instructions only when the counter reaches a set value (e.g. if counter = 5 then execute, this will have those instructions executed every half second instead of 1/10th of second).
 
Upvote 0

Melchor99

Member
Licensed User
Longtime User
Thanks, that's a good idea, I will give a check to execute clasification update or another action each half a second instead of every 1/10 second.
In addition, is there any good practice for loadbitmap instruction to optimize performance?, I use it twice per vehicle every 1/10 second to change sprites in order to give more feeling of movement in all vehicles.
Thanks
 
Upvote 0
Top