How might one create a large Bitmap in Android? - android

I am trying to build an Android application which can take several photos taken by the camera, and merge them into one giant image. For example, I might take three photos and arrange them in a vertical stack for output as a single image. Ideally, I'd like to be able to keep the images at the original size. Unfortunately, using Bitmap.createBitmap() causes an OutOfMemoryException before even approaching the size of one photo of camera dimensions. Is this possible? Or do I just need to resort to scaling the photos before trying to merge them into a single Bitmap?

What is your goal?
If your goal is to upload the combined image, have the server combine them, since it has a wee bit more CPU and RAM than do most Android devices.
If your goal is to display the combined image, since each piece of the combined image is going to be bigger than the screen size, treat the image pieces as tiles -- don't combine them, but draw them as needed as the user scrolls around the virtual combined image space.

Related

Should I store different size's image for different Image component size to improve performance?

I am working in react native with Image component and I have to use same image at multiple locations with different size. Like user profile image at:
In profile section, with a large circle of about half the device height - 600x600px,
In others contact section in the list of the contacts as thumbnail image - 80x80px,
In chatting section, sending an image to other user, image message will appear in a small box -200x200px.
My concern is should I create a small exact image size crop/compressed version for each sizes above or I must use the original size image like 1000x1000 everywhere, irrespective of the Image component size
If I create a crop version of each image of perfect size than a lot of memory will be used on device and
If I use the original image (downloaded off-course) then react-native Image component may need to do lot of efforts to crop it to perfect size. This may leads to performance issue.
Please help with the correct approach.
Since react native follows the pattern of the web so it is smart enough to compress the image size to make it to the size of the Image component you are using, it may take some time for compressing the size, which seems a more viable solution rather than creating a compressed copy by yourself for each asset. Assets may keep on changing so it will be difficult to track.
You need to put logic on the server side. When you tried to upload an image then the server will resize the image in the necessary resolution which you need to use in application along with Original.
You need to render a particular image from the server on a particular screen. For downloading an image you can use FastImage.

Images to Executables?

I have an app that uses a lot of images for drawables. However, because they are in high definition quality they take a lot of space. Is there anyway in android that I might be able to convert these images into text or since I am using Maya save them in a different format so that my app can draw them? In other words is there a way to create a code that draws the image via points given by text yet still has a good quality?

Crop image without loading into memory

I want to crop image of large size and tried using Bitmap.createBitmap but it gives OOM error. Also, tried multiple technique around createBitmap but none of them were successful.
Now I thinking of saving image to file system and crop it without loading image into memory that might solve the problem. But don't know how to do it.
User flow: User will take multiple pictures from in-app camera after each snap user can crop it manually or app will silently crop it on some predefine login and later it will send these images to server.
Can anybody guide me how I can achieve this?
There is a class called BitmapRegionDecoder which might help you, but it's available from API 10 and above.
If you can't use it :
Many image formats are compressed and therefore require some sort of loading into memory.
You will need to read about the best image format that fits your needs, and then read it by yourself, using only the memory that you need.
a little easier task would be to do it all in JNI, so that even though you will use a lot of memory, at least your app won't get into OOM so soon since it won't be constrained to the max heap size that is imposed on normal apps.
Of course, since android is open source, you can try to use the BitmapRegionDecoder and use it for any device.
I very much doubt you can solve this problem with the existing Android API.
What you need to do is obtain one of the available image access libraries (libpng is probably your best bet) and link it to your application via jni (see if there's a Java binding already available).
Use the low-level I/O operations to read the image a single scanline at a time. Discard any scanlines before or after the vertical cropped region. For those scanlines inside the vertical cropped region, take only those pixels inside the horizontal cropped region and write them out to the cropped image.

In what format should I keep the resource images for my app?

I am building a simple wallpaper app. I store the wallpaper images(.jpg) as resources in the res folder. I show the user a grid of thumbnails, which I store separately as resources(.jpg) too in res. I want the scrolling through this grid to be smooth and fast. My question is that when I load the gridview using the adapter, In the getView method I convert the resource to a bitmap and then load it in each imageView in the Grid. Would it be faster if I stored the thumbnails as .bmp in the res folder in the first place? Also I've manually created the thumbnails, rather than manipulating the large wallpapers making them at run-time. Each thumbnail is made to scale to width of 120pixels and the grid consists of 120x120 imageviews. So I was wondering how I could load these images quickly and effectively?
Im setting the adapter to the gridview inside Asyntask, but I dont notice an improvement.
Jpeg, which is lossy image compression, usually provides the best quality to size trade-off.
If you're trying to store high quality images then you're almost certainly going to want to use Jpeg.
PNG does has useful features such as allowing you to work with transparency, and, for simple block colour images outputs really small file sizes.
However, the moment you start to create photo quality images, such as wallpapers, as PNG, you're going to see monster file sizes, which on a mobile device is not going to be much fun or much appreciated by the end user.
Also larger files tend to require more system resources (CPU time and RAM), and on a mobile devices these resources are at a premium.
I would suggest that perhaps for thumbnails you might use PNG, and for the full size image use JPEG, but you might do well to see which creates the smallest file, because that is likely to give an good indication of the rendering efficiency i.e. it takes little resources to render a 800b PNG.
Changing your images to the bmp file format could make a little improvement in performance (because JPG is a compressed bitmap image that needs to be decompressed when rendered), but it's usually not worth the major increase in filesize.
I would recommend using the PNG bitmap format because it's light in both rendering and filesize.
As for the rendering in the ListView, you might want to take a look at this question and this code project.

Many and Large image loading in Android

I have a problem: (I wouldn't be here otherwise ;)
I am creating an app that has a feature for displaying "3D" models. This part is really a collection of images taken from many angles and allows the user to "rotate" the "model".
This idea is working fine, but the problem lie in the loading of the images.
I have found that there are two ways:
Load all the images into memory, and then simply switch them for the correct angle.
Load the images as we need them - we can load a few ahead of time.
However these have problems:
If I was lucky, the images would fit into memory, but they don't. They are about 1.5-2MB each and there are about 75-100 images per model. This brings the total size to about 115MB at the minimum.
If I was lucky, the image would load quicker than the user could "rotate", but they don't. The user can easily switch to an angle that is not loaded yet, resulting in a black screen for a few seconds.
I have created a loader that allows me to simply add the images that I need to a stack and the loader will then one-by-one load the images. This works fine if the user scrolls fairly slowly. My loader takes care of releasing memory when it is finished, so no matter how many images I load, the app usually won't crash as long as I specify the max images to store in memory. My loader can load the images very quickly, but there is still a few milliseconds (~250ms) for it to load the large image into memory.
Of course, the loader is on a different thread, and the loading in no way hinders UI response. That is why if the user swipes back and forth quickly, no image will actually display, as the loading and unloading are all working at the same time to result in no images :)
So, my problem: How do I provide a smooth and user-pleasing rotation of the images without loading all the images into memory?
Don't load (or store) resolution you don't need. If your user needs to zoom, an out-of-memory binary image pyramid is a cheap way to let you load only the level of zoom necessary. If your user needs to pan through an image larger than your display area, you can break your large image into smaller tiles, and only load the ones you need.
If you want to get fancy, you can write a UI-aware cache manager to preemptively load tiles you think you might need soon, and mark tiles you're pretty sure you won't need soon for preemption.
Better compression can fit more image data into memory, and speed up load time. So, pay attention to individual image compression, and don't load image quality you don't need, either.
As an extraordinary measure: since images from slightly different angles are similar to each other, you may be able to save time and space by representing the difference, instead -- look up lightfield compression. You will still need to convert from compressed form to a particular bitmap you can draw, but if the compression allows the dataset to remain in memory, you could potentially gain a lot of speed.
If you can't fit your compressed dataset into memory, there's a good chance the user will be able to swipe back and forth quickly enough to defeat your cache. So, if smoothness is your main goal, you could try for a "UI solution" by restricting the rotation rate (or the per-swipe rotation range?) to something your data loader can follow.
My only suggestion is for loading them efficiently. I assume that you are using techniques described here
If the images are of higher resolution than the screen you can calculate the sample size of the image you want to render then you can load an image that fits your screen rather than the full size image which will use much less memory. If you are already doing that then to me it seems like how you are doing it efficiently already. Perhaps you could show the user some kind of placeholder graphic while an image is loading so they won't just have blank space.
Thanks for the answers. I laughed at myself and then went to bed after reading the answers.
Let me share how I resolved this problem - it uses some pieces of the answers:
I was trying to cache the large images in memory - this is unnecessary, why not store a lower res version and then load the hi res when the user stops scrolling? Then the user can scroll as fast as he likes and there will always be images in memory to quickly paint. When the user stops/slows scrolling, we load the hi res image.
Because he will be scrolling fast, he won't be able to see the lower res' lower quality.
And, as there will only be one hi res to load, the ~250ms delay is hardly noticeable.
This really combines the best of both cases. And I can use the Android's methods for loading a lower res version of the Bitmap.

Categories

Resources