Universal Image Loader Load bitmap from memory - android

Universal Image Loader provide many ways to load the image.
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)
But all these way load image form file, I need a way to load from memory since my images was encrypted and stored in the assets folder, When I display this image, I need the following steps.
decrypt the image into bytes array.
Create bitmap from the bytes.
Load/display the image.
So it's something like this. Is that possible?
Bitmap bitmap = decrypt(encryptedImageFile);
imageLoader.displayImage(bitmap, imageView);
Currently, I am considering to save the bitmap to file and load the file, but this will take more time.

I believe the below is what you are seeking if your images are stored in image folder in assets directory, then you can get the list of images
private List<String> getImage(Context conetx) throws IOException {
AssetManager assetManager =conetx.getAssets();
String[] files = assetManager.list("image");
List<String> it=Arrays.asList(files);
return it;
}
As a note, instead of using assets dir, put the file into /res/raw and you can then access it using the following URI
android.resource://com.your.packagename/" + R.raw.<nameoffile>

I think you need to understand this. You must know, If you have read the source code of universal-image-loader, the order of loading a image into a ImageView after the image's url is provided, is: memory, SDCard(if set), internet. That means after you called, ImageLoader.display(url, imageview);, it will look for the Bitmap from memory first, if it doesn't exist, if will look for the file of the image from SDCard then, if the file exist, if will convert the file into a Bitmap, then load the Bitmap into the ImageView and store it in memory. But if the file doesn't exist, it will download the image file of the url, then store the file into the SDCard and convert the file into a Bitmap and load the Bitmap into memory. Most importantly, I recommend you to read source codes of it, if you are confused with what I post above.
So, it is unnecessary for you to load the Bitmap from memory, ImageLoader will do it for you.

Lets choose own scheme so our URIs will look like "stream://...".
Then implement ImageDownloader. We should catch URIs with our scheme and return image stream.
public class StreamImageDownloader extends BaseImageDownloader {
private static final String SCHEME_STREAM = "stream";
private static final String STREAM_URI_PREFIX = SCHEME_STREAM + "://";
public StreamImageDownloader(Context context) {
super(context);
}
#Override
protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
if (imageUri.startsWith(STREAM_URI_PREFIX)) {
return (InputStream) extra;
} else {
return super.getStreamFromOtherSource(imageUri, extra);
}
}
}
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.imageDownloader(new StreamImageDownloader(getApplicationContext()))
.build();
ImageLoader.getInstance().init(config);
ByteArrayInputStream stream = new ByteArrayInputStream(imgBytes);
String imageId = "stream://" + stream.hashCode();
DisplayImageOptions options = new DisplayImageOptions.Builder()
.extraForDownloader(stream)
.build();
ImageLoader.getInstance().displayImage(imageId, imageView, options);

Related

How to make Glide use previously downloaded image as placeholder

Is it possible to show previously downloaded image in Glide as placeholder while downloading new image.
Like I have an image loaded in imageview using glide. Now the imageurl is changed, so while loading this new image is it possible to keep displaying the old image (might be from cache).
What I want is while the new image is being loaded from the URL, is it possible to keep the current image as placeholder.
I found the answer to this in the discussion here - https://github.com/bumptech/glide/issues/527#issuecomment-148840717.
Intuitively I also thought of using placeholder(), but the problem is that as soon as you load the second image, you loose the reference to the first one. You can still reference it but it is not safe as it may be reused by Glide or recycled.
The proposed solution from the discussion is to use thumbnail() and load the first image again. The load will return the first image immediately from the memory cache and it will look as if the image did not change until the second image is loaded:
String currentImageUrl = ...;
String newImageUrl = ...;
Glide.with(this)
.load(newImageUrl)
.thumbnail(Glide.with(this)
.load(currentImageUrl)
.fitCenter()
)
.fitCenter()
.into(imageView);
Glide have a capability of getting the bitmap of the image from that url, so just get it and then save it to a desired storage into your phone, and after that in your .placeholder() just use that bitmap when you are trying to get another image , take a look at this snippet
/** Download the image using Glide **/
Bitmap theBitmap = null;
theBitmap = Glide.
with(YourActivity.this).
asBitmap().
load("Url of your image").
into(-1, -1).
get(); //with this we get the bitmap of that url
saveToInternalStorage(theBitmap, getApplicationContext(), "your preferred image name");
/** Save it on your device **/
public String saveToInternalStorage(Bitmap bitmapImage, Context context, String name){
ContextWrapper cw = new ContextWrapper(context);
// path to /data/data/yourapp/app_data/imageDir
String name_="foldername"; //Folder name in device android/data/
File directory = cw.getDir(name, Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,name_);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.e("absolutepath ", directory.getAbsolutePath());
return directory.getAbsolutePath();
}
/** Method to retrieve image from your device **/
public Bitmap loadImageFromStorage(String path, String name)
{
Bitmap b;
String name_= name; //your folderName
try {
File f=new File(path, name_);
b = BitmapFactory.decodeStream(new FileInputStream(f));
return b;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
return null;
}
/** Retrieve your image from device and set to imageview **/
//Provide your image path and name of the image your previously used.
Bitmap b= loadImageFromStorage(String path, String name)
ImageView img=(ImageView)findViewById(R.id.your_image_id);
img.setImageBitmap(b);

Universal Image Loader and BitmapDrawable

We have an image in B64, an we want to use that image as loading image in Universal Image Loader while a better image isn't loaded from an url. So we create a bitmap from that url in b64 and convert it into a BitmapDrawable.
The result is shown fine if I do:
imageView.setImageDrawable(bitmapDrawable)
But, on DisplayImageOptions, if I set that bitmapDrawable as image on loading, the image is never shown. I'm doing the following:
final DisplayImageOptions imageOptions = mDisplayImageOptionsDefaultBuilder.
.showImageOnLoading(bitmapDrawable)
.showImageOnFail(bitmapDrawable)
.showImageForEmptyUri(bitmapDrawable)
.build()
As you can see, I am setting the bitmap drawable not only as image when loading, but as image when fails too (as we don't want that image to change in case of error while loading the better image from an url). The result of that is that the bitmap drawable is never shown. What are we doing wrong?
UPDATE:
After debugging what was happening I've seen that the problem is not the bitmap drawable, it is supported and working fine. The problem was that I am using a default display options builder (mDisplayImageOptionsDefaultBuilder), than at some point did:
final DisplayImageOptions imageOptions = mDisplayImageOptionsDefaultBuilder.
.showImageOnLoading(loadingResource)
.showImageOnFail(errorResource)
.showImageForEmptyUri(errorResource)
.build()
So there's a bug in Universal Image Loader, because now I'm creating a display image options with:
.showImageOnLoading(bitmapDrawable)
Another "solution" is do:
final DisplayImageOptions imageOptions = mDisplayImageOptionsDefaultBuilder.
.showImageOnLoading(0)
.showImageOnLoading(loadingResource)
.showImageOnFail(errorResource)
.showImageForEmptyUri(errorResource)
.build()
But internally it stores that there's a resource stored, so my drawable is not shown but the stored resource instead. Creating a new DisplayImageOptionsBuilder worked for me, but it would be nice that if the showImageOnLoading is set with a drawable, then the old resource was automatically cleared.
Thanks in advance.
UIL only supports the following schemes:
"h t t p://site.com/image.png" // from Web
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)
Use these schemes.
Universal Image Loader also provide to use the Background functionality.Please check the below coed for it:-
Here Uri is the path of the folder image OR the URL of the image.
imageLoader.loadImage(YOUR_URL, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
layout.setBackgroundDrawable(new BitmapDrawable(loadedImage));
}
});

Download images and save it

I'm working on a school android project.
I need to have a download button which downloads a picture(when we have class)
And after display it in another activity(even in offline mode, and after quiting)
I've tried picasso, but I can't get it to save and use it in offline mode.
For you to support offline mode, You need to Save the image on your disk because when your cache is cleared, The image is cleared as well.
You can easily use Glide to Solve this, also storing on device and retrieving
You can Learn more about Glide here http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
/** Download the image using Glide **/
Bitmap theBitmap = null;
theBitmap = Glide.
with(YourActivity.this).
load("Url of your image").
asBitmap().
into(-1, -1).
get();
saveToInternalStorage(theBitmap, getApplicationContext(), "your preferred image name");
/** Save it on your device **/
public String saveToInternalStorage(Bitmap bitmapImage, Context context, String name){
ContextWrapper cw = new ContextWrapper(context);
// path to /data/data/yourapp/app_data/imageDir
String name_="foldername"; //Folder name in device android/data/
File directory = cw.getDir(name_, Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,name);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.e("absolutepath ", directory.getAbsolutePath());
return directory.getAbsolutePath();
}
/** Method to retrieve image from your device **/
public Bitmap loadImageFromStorage(String path, String name)
{
Bitmap b;
String name_="foldername";
try {
File f=new File(path, name_);
b = BitmapFactory.decodeStream(new FileInputStream(f));
return b;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
return null;
}
/** Retrieve your image from device and set to imageview **/
//Provide your image path and name of the image your previously used.
Bitmap b= loadImageFromStorage(String path, String name)
ImageView img=(ImageView)findViewById(R.id.your_image_id);
img.setImageBitmap(b);
Thanks to #Droidman :
How to download and save an image in Android
Of course you can perform downloading and managing images by yourself,
but if your project is quite complex already, there are a lot of
libraries around and you do not need to reinvent the wheel. I won't
post code this time since there are a lot of examples, but I'm going
to tell you about 2 most useful libraries (IMO) related to image
downloading.
1) Android Volley. A powerful networking library created by Google and
covered by official documentation. POST'ing or GET'ing data, images,
JSON - volley will manage it for you. Using volley just for image
downloading is a bit of an overkill in my opinion.
2) Picasso
Image downloading and caching, perfect for
ListView/GridView/RecyclerView. Apache 2.0 license.
3) Fresco
Quite a new image loading library created by Facebook. Progressive
JPEG streaming, gifs and more. Apache 2.0
You could use Android Library called Universal Image Loader:
https://github.com/nostra13/Android-Universal-Image-Loader

Save images in external storage from Parse.com

I want to download images from parse database table and store all the images in a external memory folder. Is it possible ? If yes , how ??
Yes of course it is possible. But you need to follow some steps:
-Start downloading the image Url from your Parse object:
String url=yourParseObject.getParseFile("Image").getUrl();
-Now pass that url to this function:
public static Drawable loadImageFromUrl(String url) {
InputStream inputStream;
final ImageView imageView = (ImageView) rowView.findViewById(R.id.image);//Your imageView in the layout
AsyncImageLoader async=new AsyncImageLoader();
Drawable cachedImage = async.loadDrawable(
url, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable,
String imageUrl) {
imageView.setImageDrawable(imageDrawable);
}
});
imageView.setImageDrawable(cachedImage);
return cachedImage;
}
-If you want to save that in SD Card instead of ImageView, export that inside of the method (Drawable imageDrawable,String imageUrl) in drawable or bitmap form.
Hope it helps!
you can do that just you need to write code for download image from url and for url you can get using ParseFile.getUrl() and for downloading file you can check this tutorial
http://javatechig.com/android/download-image-using-asynctask-in-android
You can get download image from parse.com in bitmap then store this bitmap as image in your file directory as you want.
Refer this
android-parse-com-image-download-tutorial

How to delete a bitmap image which is stored on the sd card in android

In my application I have a grid view of images and when a user clicks an image then it will open the image in fullscreen. The images are loaded from the SD card as follows:
File sdDir = new File("mnt/sdcard/Pictures");
File[] sdDirFiles = sdDir.listFiles();
for(File singleFile : sdDirFiles) {
String filePath = singleFile.getAbsolutePath();
Bitmap bmp = scaleBitmap(filePath);
photos.add(bmp);
}
mThumbIds = photos.toArray(new Bitmap[(photos.size())]);
}
Scale bitmap is a method which decodes each file into a bitmap and then scales the bitmap before returning it.
I then have another Activity which loads the images fullscreen once they have been clicked. I have a menu button "Delete", from which I would like to delete the file on the sdcard which represents the bitmap I see on the screen.
The problem I have is that there is no way to get the file name from the Bitmap object, so therefore I cannot delete the file.
Any help will be greatly appreciated.
You could extend the Bitmap class and add a filename field. Or, you could pass the filename to your new activity in the intent bundle.

Categories

Resources