3

This is a bit of a followup to my last question: Canvas is drawing too slowly

Now that I can draw images more quickly, the problem I am faced with is that the actual loading of the images takes far too long.

In the app I am working on, the user is able to play back video frames (jpegs) in succession, as though he is viewing the video in realtime. I have been using BitmapFactory.decodeFile() to load each jpeg in a Bitmap. I'm unable to load all images at once since there are about 240 of them, and that would use up all of my heap space. What I have been doing is preloading up to 6 at a time into an array by way of a separate thread in order to cut down on the time it takes for each image to display.

Unfortunately, it takes somewhere between 50 and 90ms to load an image, and I need to show an image every 42ms. Is there a faster way to load images possibly?

For clarification, these images are in a folder on the SD card, and they are all 720x480 jpegs. I am sampling them at half that size to cut down on memory usage.

Community
  • 1
  • 1
BigFwoosh
  • 1,197
  • 10
  • 17
  • Have you seen any difference when using the internal memory or when using png instead of jpeg? – mibollma Jun 29 '11 at 20:27
  • I haven't tried internal memory yet, I suppose I'll give that a try next. I started out using png, but they were much larger than jpeg and the jpegs already take up about 8MB on the device. – BigFwoosh Jun 29 '11 at 20:36
  • It does seem a little faster using internal memory, but it's still not fast enough for what I'm doing. I think what I really need is a way to store all the images without sacrificing quality. I can store them all in memory if I set inSampleSize to 4, but the quality drops substantially. – BigFwoosh Jun 29 '11 at 21:05

2 Answers2

1

I ended up doing this quite a bit differently than I had originally envisioned. There was quite a bit to it, but here's the gist of how I achieved my goal:

  1. All images are stored on SD card and written to one file (each image takes up X bytes in the file)
  2. Use native code to read from and write to the image file
  3. When requesting an image, I pass the index of the image in the list and a bitmap object (RGB_565) to the native code using a JNI wrapper
  4. The native code locks the bitmap surface, writes pixel data (as a uint8_t**) directly to the bitmap, then unlocks it
  5. The image is rendered to the screen

By doing it this way, I only needed to store one image in memory at a time, and I was able to bypass garbage collection (since the bitmap was only created once and then repopulated natively). I hope someone else might find this strategy useful.

BigFwoosh
  • 1,197
  • 10
  • 17
0

Guess you already tried all methods in this tutorial http://www.higherpass.com/Android/Tutorials/Working-With-Images-In-Android/2/ and chosen the fastest. Maybe tweaking resizing can decrease loading time.

Best of all would of course be if you didn't have to resize the images at all. If you have full control of the images maybe you could try to pack them as sprites, see article http://www.droidnova.com/2d-sprite-animation-in-android,471.html

Kennet
  • 5,736
  • 2
  • 25
  • 24
  • Unfortunately I am going to have to resize the images since many Android devices nowadays can record video at high resolutions, but their screen dimensions are smaller. I also can't reference the images as resources, since they are actually generated from a video file on the device at runtime. I suppose I can see about resizing the images as they are generated. – BigFwoosh Jun 29 '11 at 20:34