How to save images in .thumbnail folder with proper format? - android

I need to download images from server and store as thumbnails directly.
and for display images also i need to use images from .thumbnails folder directly. i am not getting how to create and save images as .thumbnail . and how to use images from that .thumbnail file.i searched online but everywhere only this below code present.
Bitmap thumb = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(file.getPath()), width, height);
any help?

Please check below code which helps you.
Follow below steps:
Calculate the maximum possible inSampleSize that still yields an image larger than your target.
Load the image using BitmapFactory.decodeFile(file, options), passing inSampleSize as an option.
Resize to the desired dimensions using Bitmap.createScaledBitmap().
Now you have your bitmap ready and you can save it any where using the following code
Bitmap thumbnail;
File thumbnailFile = ...;
FileOutputStream fos = new FileOutputStream(thumbnailFile);
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
hope it helps you and save your time.
Or use Glide library which store image as a full image and 1 thmbnail image which is power caching library which loads image quickly and once download image after load image from cache not from network.
Below is a Glide link please read it advantages and features and after used into your applications.
https://github.com/bumptech/glide

Related

Loading and cropping bitmaps without Out Of Memory exception

I need to crop images from Facebook, Instagram or the device itself. At the end of the user flow (where he selects them), all the said images should be send to the server. But all in the same width/height ratio (e.g. 3/2), therefore I need to crop the images manually.
Here a simple example of what's going on in my upload service and the cropping:
Bitmap bitmap = ImageLoading.getLoader(UploadService.this).loadImageSync(path);
//crop calculations
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, w, y);
String croppedPath = saveCroppedImage(croppedBitmap);
I then read this file from the filesystem and encode it to BASE64 to send it to the backend.
When I have to do this for multiple images, I regularly get an OOM Exception. Maybe I'm going at this the wrong way.. Cropping on the server side is really the last thing I want to do, because then the backend would have to query Facebook or Instagram.
Loading a scaled version of the bitmap isn't an option, I'm not displaying it on the device.
I have tried:
System.gc()
Bitmap.recycle();
Should I really use largeHeap in my manifest?
note: I'm using Universal Image Loader for the user flow as well, that's why I'm using it in the upload service too.
I think you should add largeHeap = true in the AndroidManifest file.
Secondly, If you are using Universal ImageLoader, you can download the bitmap in smaller size. Please have a look at this code:
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options); // This bitmap will be of specified size.
You can further read about Universal Image Loader by following the link.

How to store images which are loading from a url [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am new to android. I have some images stored at some path on server. In my application i want that the images should be loaded once from the server and next time the user opens the application the app should not load it again. Please tell me how should i store these images. Please help.
For store image on app cache or internal storage(sdcard0) you can use library like Universal-Image-Loader , Aquery, Picasso etc.
These library helps you to make image loading faster, save images on cache memory or data.
You can download this library from here
Universal Image Loader : https://github.com/nostra13/Android-Universal-Image-Loader (Just import library in your workspace and use it)
Aquery : https://github.com/androidquery/androidquery (You can use Aquery-android.jar file for use Aquery)
Universal image loader has more functionality than Aquery.
Hope this helps you out.
You can store image in file. You need only set unique name to image file, an example md5 hash of url.
You can save image in file use follow code:
File file = File(filePath)
try {
FileOutputStream outStream = FileOutputStream(file)
bitmap!!.compress(Bitmap.CompressFormat.PNG, 100, outStream)
outStream.flush()
outStream.close()
}catch(e: Exception){
Log.e("log", "error save image to cache $filePath")
}
}
and read from file:
try{
BitmapFactory.Options optionsBitmapFactory = BitmapFactory.Options()
optionsBitmapFactory.inPreferredConfig = Bitmap.Config.ARGB_8888
Bitmap bitmap = BitmapFactory.decodeFile(filePath, optionsBitmapFactory)
}catch(e: Exception){
Log.e("log", "error load image from cache $filePath")
}
There are several image loader libraries for it. One of them is Universal Image loader and Glide
You can refer this Picasso v/s Imageloader v/s Fresco vs Glide
It will store images in cache and next time will provide image from cache. For server images Universal Image loader and Glide library is highly recommended. You can also set placeholder image.
There are two way :-
Do cache images for an example just look at picaso library.
//Code how to use picaso :-
/Initialize ImageView
ImageView imageView = (ImageView) findViewById(R.id.imageView);
//Loading image from below url into imageView
Picasso.with(this)
.load("YOUR IMAGE URL HERE")
.into(imageView);
Store images to storage either external or internal and fetch second time from storage. you can use again picaso callback to save bitmap cio.economictimes.indiatimes.com
There are some third party libraries available for these purpose which would save some development effort.
Below are some of them:
Picasso
Glide
Universal image loader
Here is some libs for loading image from URL and it will store image in to memory as cache.
UIL : flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.
PICASSO :
Handling ImageView recycling and download cancelation in an adapter.
Complex image transformations with minimal memory use.
Automatic memory and disk caching.
First you must make sure your application has permission to write to the sdcard. To do this you need to add the uses permission write external storage in your applications manifest file. See Setting Android Permissions
Then you can you can download the URL to a file on the sdcard. A simple way is:
URL url = new URL ("file://some/path/anImage.png");
InputStream input = url.openStream();
try {
//The sdcard directory e.g. '/sdcard' can be used directly, or
//more safely abstracted with getExternalStorageDirectory()
File storagePath = Environment.getExternalStorageDirectory();
OutputStream output = new FileOutputStream (new File(storagePath,"myImage.png"));
try {
byte[] buffer = new byte[aReasonableSize];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
} finally {
output.close();
}
} finally {
input.close();
}
EDIT : Put permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

what is the best way to work with Images in SqLite android?

I am working with a customizable database with pictures. Right now I am taking pictures as it is from the sdcard and encoding it in base64 String and then putting it in the database. but whenever I am trying decoding it and showing it in my view, I am getting Out of memory error. Can any one one tell me what is the best procedure to do it? Shall I change the size of the pictures before encoding it?
I want to re-size all of the pictures into 512*512.
Image to Base64 is very heavy operation in android. Consider saving the images on the external/internal memory and save the file path in the sqlite database.
You can convert your image to byte array then store values in sql by using BLOB type and vice versa.
As you mentioned you want to resize the images to 512*512, you can scale the image using below code,
Create bitmap from captured image and then use below line
Bitmap resizedBitmap = Bitmap.createScaledBitmap(myBitmap, 512, 512, false);
It will give you a smaller image, you can also consider compressing the image to reduce in size,
OutputStream imagefile = new FileOutputStream("/your/file/name.jpg");
// Write 'bitmap' to file using JPEG and 50% quality hint for JPEG:
bitmap.compress(CompressFormat.JPEG, 50, imagefile);
Now, you have two options,
Save the scaled and compressed image into a file and save the path of that file in db. (Better way)
Convert the scaled and compressed image to base64 string and save in db.
Althought base64 is , as many answers said, a heavy operation for android, if done properly, it should not be a problem.
There are many reasons a bitmap could be required to be saved to a DB , (photo of a invoice ticket, for example?), and this is the way i do it.
first, create a new , smaller bitmap like #Swapnil commented.
and second, correctly use the bitmap transformation methods, i've been using these (look below) two so far and haven't had any memory issue on many different devices.
link to my BitmapUtils transformation methods

Set wallpaper from external storage

So I've got my image gallery project all set up with images saved online and not within the application. It works great. But what I want to do is get the facility to set the image as a wallpaper.
I've got the image to download and save in the external storage as packagename.jpg
Everywhere I've searched for examples on how to set the wallpaper all seem to be based on the image being within the application.
Anyone have any pointers on how to use wallpapermanger to set an image from external storage as the wallpaper?
You need to first retrieve the file from the SDCard and decode the image into a Bitmap using BitmapFactory then you can set the bitmap using WallpaperManager's setBitmap() method.
File file = new File(Environment.getExternalStorageDirectory(), "/directory/yourimage.jpg");
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getBaseContext());
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
wallpaperManager.setBitmap(myBitmap);

Given a full path of an image file, how to get its thumbnail?

It seems the answers I searched online (including stackoverflow.com) get the image file id through gallery selection.
I have created my own file explorer.
Then how to do that?
I can create my own small size image; but I think it would be faster if we can make use of an exisiting thumbnail; and if it does not exist, I would prefer to create a thumbnail that is saved for later use.
[Update:]
OK, thanks for advice. So I will not create a thumbnail in the device, to avoid to use too much space.
Then is is better to do two steps:
Step 1: look for an exisiting thumbnail for the image file if it exists.
Step 2: if no thumbnail exists, then create my own small size bitmap (not save the it).
Then how to do Step 1, if I do not use the Gallery intent?
[Update 2:]
I also want to get the thumbnail of a video file.
I can use MediaMetadataRetriever to get a frame at any point of time, and rescale the image to a thumbnail. But I find it is very slow: I have 4 video files in the folder, and I can sense the delay.
So I think the better way to retrieve an existing thumbnail.
If I only know the file path and file name, how can I get it?
I think this question is the same as my original one, just it has more sense to do so.
You shouldn't be using specific files for tumbnail, especially not creating tumbnails. What if the user has a lot of images and you store a tumbnail of each picture which gets viewed in your explorer. That would generated a whole lot of duplicated and unwanted data. The calculations from resizing the images each time overweighs the amount of data that would need to be stored.
I would suggest you have a default icon on images in the explorer and then resizing the images in a diffrent thread, replacing your default tumbnail as they are resized.
You could downsize the existing images on the fly:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
then
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inDither = true;
opts.inJustDecodeBounds = false;
opts.inSampleSize = (int)Math.pow(2.0,Math.floor(Math.log(scale_factor)/Math.log(2)));//for example double scale_factor=(double)width/desired_dimension;
and finally:
Bitmap bm = BitmapFactory.decodeFile(image_path,opts);
You could load in a separate thread ranges of existing files and update only those ones when needed.
You can use ThumbnailUtils. Look up the this utility method. Probably fits your need without much hassles. Creating duplicate downsized images is a bad design as that it will end up unnecessary data.
Bitmap resizedImage = ThumbnailUtils.extractThumbnail(rescaledImage, imagePixel, imagePixel);

Categories

Resources