I'm trying to resize large images (16MP) on Android down to smaller but still large (8MP) images. I tried some approaches I've found on SO with sampled or scaled loads into memory, but neither one of these sizes fits into a decoded bitmap in memory reliably.
Is there a way I go straight from input file to output file while using a minimal amount of memory? Some sort of streaming decode/encode?
Related
I'm building an application with very big sized images.
Almost all of my UI components are made of ImageViews.
I only have to show 12 images(ui components) on my first activity, but it consumes 80mb on startup.
The images are divided into each drawable directories using Android Drawable Importer.
By doing this I was able to reduce the runtime memory(which I can see on the Android studio's device monitor) to half, but it is still consuming 80~120mb of memories, which I believe is too much.
The first question is, isn't 80~120mb too much for a four screen(two activities, three fragments) application?
The second is, if it's too much then, what and how can I do to reduce memory usage?
When working with images keep in mind that there is a HUGE difference between compressed format (jpg, png..) and Bitmap. Computing the size of a Bitmap is pretty easy, it's width * height * 4 bytes (assuming that the bitmap has the default configuration argb888). So a full hd image that compressed is xy kb, when decompressed will occupy 8294400 bytes (~8mb). So my advice to reduce memory consumption is... scale down your images. You're asking if 80-120 mb is too much, well it seems like a lot but it really depends on what you're doing. What happen if you force garbage collection (there should be an icon in the device monitor)?Another thing to take into account is how to decompress the images, refer to this and use a library (Picasso, Glide..).
The main purpose of this question is to know what is the best option to choose between PNG and JPG for android development considering the following scenarios
1) is it a good option to use jpg image as background?
2) Will .jpg image take more time to load compared to .png?
3) Will .jpg take more time for rendering/loading compare to .png?
I have seen big difference in image size when we are using png images.
One of my .png image size is 4.1 MBs and that same image with .jpg image format the size is reduced to 2.9MBs
Need suggestion from Experts specially.
Info: To reduce app size. i am still compressing images by using compress png and compress jpeg
Image size difference is huge. ie. 4.1 MBs png -> 2.9 MBs jpg after compressing it reduced to 654.6 KBs..
To set image as BACKGROUND i didn't found any issue...
It's just a question of quality and details.
Just for my opinion, for a big background resolution is better to use a JPG, if you don't need any transparency on the image, with the right compromise between quality and size of file,
PNG format is a lossless compression file format, which makes it a common choice for use on the Web. PNG is a good choice for storing line drawings, text, and iconic graphics at a small file size.
JPG format is a lossy compressed file format. This makes it useful for storing photographs at a smaller size than a BMP. JPG is a common choice for use on the Web because it is compressed. For storing line drawings, text, and iconic graphics at a smaller file size, GIF or PNG are better choices because they are lossless.
From:http://www.labnol.org/software/tutorials/jpeg-vs-png-image-quality-or-bandwidth/5385/
The main difference is image quality. The PNG format uses a lossless compression, while JPEG uses a lossy one optimized for photos. It depends what is shown on the image if JPEG is a valid alternative. In artificially generated images of geometric figures like logos the artifacts coming from JPEG compression can be easily seen.
It's a question of quality of the images. If you're ok with the loss of quality just use it instead.
A bitmap file is a .png, .jpg, or .gif file. Android creates a Drawable resource for any of these files when you save them in the res/drawable/ directory.
I'm making an app for android. I use images as screen background.
Time of setting 1848x1080 jpg in imageView is about 65-80ms on my phone. File size is 900kb.
When I reduce image's quality and size (1369x800), the size of file is about 150kb.
But time of loading that image is about 55-60ms! Not much of a difference.
Why is that? Can anyone help me with this - how to prepare images well to be loaded as quickly as possible in android and still look well on Full HD screen?
That is because Android as an operating system has to create an internal file descriptor in each case. That takes always the same time, so you don't win anything if the file size changes.
I would recommend you to preload the files you quickly need and hold them in the memory (caching). This will maybe blow up the memory used by your app, but it will allow you to display those images really fast.
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.
I'm downloading images from the internet and then displaying them scaled on the screen. The idea is to use inSampleSize so I can scale large images while decompressing and prevent OutOfMemory exception. But in order to find inSampleSize I need to know image resolution. It can be obtained using inJustDecodeBounds option.
The problem is that I can't pass it the stream and download the image from the internet directly, because it will be downloaded twice (first to get the size, then to get the scaled Bitmap). I can't download the image and store it in RAM, because image size may be large. The only solution left is to download the image to SD card / internal memory and read it from there, but when user has no space left bad things are going to happen.
The question is - is there any way to do it without relying on the storage and RAM memory which doesn't require the image to be downloaded twice? Or maybe BitmapFactory doesn't download whole image when it's using inJustDecodeBounds, but just headers?
Thanks
If you're downloading a PNG, GIF or JPG it should be possible to read the file headers to determine the width and height, which should mean you avoid having to download the entire file.
This post has some C# code for reading the width and height from the headers for the above format which you could port to Java for use in Android.