How can i just download image with universal-image-loader - android

as far as I know, universal-image-loader provide 2 kinds of methods to display images. imageLoader.loadImage and imageLoader.displayImage. But those 2 methods must bind to UI element to display. Can I just download files for cache in a thread (for future display). I don't need to display those image right now.

You can still use UIL. Based on the displayOptions used below the images would be cached.
Refer here - https://github.com/nostra13/Android-Universal-Image-Loader
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, displayOptions, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});

Can I just download files for cache in a thread (for future display).
I don't need to display those image right now.
You can download files using Executor or creating a thread. You don't need to use universal imageloader.
http://developer.android.com/reference/java/util/concurrent/Executor.html.
You can also use a DownloadManager and save the file in sdcard. You can retrieve the same for later use.
http://oodlestechnologies.com/blogs/Downloading-and-Retrieving-Files-on-SD-card-in-Android-using-Android-SDK-in-Eclipse
To cache bitmaps you can write the images to a folder in sdcard.
Caching bitmaps
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html.
You cache bitmaps in memory or disk. The link has details regarding the topic.
You basically use UIL ofr displaying images in listview or grdiview. To use UIL in listview or gridview you can do as below.
https://github.com/nostra13/Android-Universal-Image-Loader. It is based on Lazy List(works on same principle). But it has lot of other configurations. You can display a error image if downlaod failed. Can display images with rounded corners. Can cache on disc or memory. Can compress image.
In your custom adapter constructor
File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_id)//display stub image
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20))
.build();
In your getView()
ImageView image=(ImageView)vi.findViewById(R.id.imageview);
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options
You can configure with other options to suit your needs.
Along with lazy loading/Universal Image Loader you can view holder for smooth scrolling and performance. http://developer.android.com/training/improving-layouts/smooth-scrolling.html.

Theres loadImage(String uri, ImageLoadingListener listener), I think you can call it with null for the listener if you don't need one.

Adding to #Robin Srivastava's answer:
You must also instantiate the ImageLoader context, for example:
imageLoader = ImageLoader.getInstance(); before you can use the loadImage method. The displayOptions parameter is also optional so you can exclude that if need be.

Using UIL,we can save the image when the image is fully loaded.
using ImageLoading Listener when loading is completed the listener has a method called onLoadingComplete() we can get Bitmap of the image and we can store this Bitmap using the below method saveImage()
Bitmap imageBitmap=null;
ImageLoader.getInstance().displayImage(String.valueOf(mediaPath), imageView, options, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case UNKNOWN:
message = "Unknown error";
break;
case IO_ERROR:
message = "I/O error";
break;
case NETWORK_DENIED:
message = "Network Denied";
break;
case OUT_OF_MEMORY:
message = "Out of memory";
break;
case DECODING_ERROR:
message = "decoding error";
break;
}
Toast.makeText(FullScreenActivity.this, message, Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//we can get imageBitmap here when loading is completed
imageBitmap=loadedImage;
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
Use this method to save the file in your local storage
public void saveImage(){
if(imageBitmap!=null){
File dir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + “/Images/");
if (!dir.exists()) {
if (dir.mkdirs()) {
Log.i(TAG, "Directory created");
}
}
//put your image file name here
File mypath=new File(dir,"yourImageName.png");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
if(imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)){
showToast("Successfully downloaded");
}
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Toast toast=null;
private void showToast(String message) {
if (toast != null) toast.cancel();
toast = Toast.makeText(FullScreenActivity.this, message, Toast.LENGTH_SHORT);
toast.show();
}

Related

I am unable to send image from recyclerview.adapter to another activity

#Override
public void onBindViewHolder(final ViewHolder holder ,int position) {
Glide.with(c)
.load(images.get(position))
.placeholder(R.mipmap.ic_launcher)
.into(holder.img);
holder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
String fileName = "bitmap.png";
FileOutputStream stream = c.openFileOutput(fileName,Context.MODE_PRIVATE);
Intent showBigPicture = new Intent(c,showBigPicture.class);
Bitmap bitmapImage = BitmapFactory.decodeFile(images.get(position));
bitmapImage.compress(Bitmap.CompressFormat.PNG,100,stream);
stream.close();
bitmapImage.recycle();
showBigPicture.putExtra("image",fileName);
c.startActivity(showBigPicture);
}catch (Exception e){
e.printStackTrace();
}
}
});
}
this is showing in logCat " Unable to decode stream: java.io.FileNotFoundException: android.support.v7.widget.AppCompatImageView{e22d977 V.ED..C. ...P.... 0,0-540,890 #7f0b0061 app:id/img}: open failed: ENOENT (No such file or directory)"
I believe you want to follow this answer on saving Bitmap images. I believe the reason you're getting a FileNotFoundException is because you're providing the URI to a file that doesn't exist yet to the decodeFile function that's quite possibly a URL from what I can tell. In short, to save a bitmap:
Create a new File(filename)
Decode file using getName on the File from step 1
Create FileOutputStream from File
Compress the bitmap image into the FileOutputStream
From what I can surmise from your question, it looks as though you're showing a images in a RecyclerView and when an image is clicked, you want to open another activity which shows a version of the full image. If that's close to your use-case, and you're using Glide, I would recommend taking advantage of its built-in automatic caching feature to reduce network calls instead of manually saving the file.
By default, disk and memory-based caching is enabled in Glide as long as the same filename, path, or URL are used to obtain the image on each Glide.load(...). If you'd like to manipulate how the caching occurs, use the DiskCacheStrategy enum to control that every time you load the image:
Glide.with(c)
.load(images.get(position))
.diskCacheStrategy(DiskCacheStrategy.SOURCE) # Will cache the source downloaded image before any transformations are applied
.placeholder(R.mipmap.ic_launcher)
.into(holder.img);
If you still want to save the file for other reasons, use a SimpleTarget instead of loading directly into your ImageView like so:
Glide.with(c)
.load(images.get(position))
.diskCacheStrategy(DiskCacheStrategy.SOURCE) # Will cache the source downloaded image before any transformations are applied
.placeholder(R.mipmap.ic_launcher)
.asBitmap()
.into(new SimpleTarget<GlideDrawable>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
holder.img.setImageDrawable(new BitmapDrawable(bitmap));
saveImage(bitmap); # This being an encapsulation of the steps outlined earlier
}
});

Android: Universal Image Loader - Add new image to cache

I am successfully integrate Universal Imageloader in my Gallery App to show the images from the phone storage
But new images (captured from the camera /processed images) stored in the app's specified folder doesn't appear in the gallery. even the application restarted.
May be due to this error
W/ImageLoader: Try to initialize ImageLoader which had already been initialized before. To re-init ImageLoader with new configuration call ImageLoader.destroy() at first.
I think add the details of new image to the cache will resolve the problem. but don't know how . please help
code : Activity Extends Application
DisplayImageOptions defaultDisplayImageOptions = new DisplayImageOptions.Builder() //
.considerExifParams(true)
.resetViewBeforeLoading(true)
.showImageOnLoading(R.drawable.nophotos)
.showImageOnFail(R.drawable.nophotos)
.delayBeforeLoading(0)
.build(); //
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.defaultDisplayImageOptions(defaultDisplayImageOptions)
.memoryCacheExtraOptions(480, 800).threadPoolSize(5)
.build();
ImageLoader.getInstance().init(config);
load all album
PhoneMediaControl mediaControl = new PhoneMediaControl();
mediaControl.setLoadalbumphoto(new loadAlbumPhoto() {
#Override
public void loadPhoto(ArrayList<AlbumEntry> albumsSorted_) {
albumsSorted = new ArrayList<PhoneMediaControl.AlbumEntry>(albumsSorted_);
if (mView != null && mView.getEmptyView() == null) {
mView.setEmptyView(null);
}
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
}
});
mediaControl.loadGalleryPhotosAlbums(mContext, 0);
is there any way to add new processed image to the cache or already initiated imageloader
You just have to load the your image with universal image loader it will automatically cache it.
Loading
ImageLoader imageLoader = ImageLoader.getInstance();
Uri uri = Uri.fromFile(new File("/DCIM/Camera/1470634175974.jpg"));
imageLoader.loadImage(uri.toString(), new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
UNIVERSAL IMAGE LOADER ACCEPTED URI schemes
"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)
Initialize your UniversalImageLoader instance only once inside onCreate() of your Application class, not inside each Activity or elsewhere.
I found this will reslove the problem using the function loadImageSync();
ImageLoader.getInstance().loadImageSync(filepath);

Load Drawable object into ImageView using Picasso or Glide or any cashing library - Android

I need to load App icon into image view. It is too slow to load it in list view.
I tried to use Picasso or Glide to load it.
I could not find out how to load Drawable object (NOT FROM RESOURCES) into image view using any of those libraries?
The function for getting the drawable:
public Drawable getIcon() {
if (icon == null) {
icon = getResolveInfo().loadIcon(ctx.getPackageManager());
}
return icon;
}
You can do this
Drawable icon = ....
Bitmap bitmap = ((BitmapDrawable) icon).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bitmapdata = stream.toByteArray();
Glide.with(context)
.load(bitmapdata)
.into(imageView);
But i am not sure that in this case the Glide (or Picasso) will be use the cache.
You can create your own RequestHandler for Picasso. There is a tutorial here.
For example,
class AppIconRequestHandler extends RequestHandler {
#Override
public boolean canHandleRequest(Request data) {
return true; // or do validation here
}
#Override
public Result load(Request request, int networkPolicy) {
// Not sure if DISK or correct or if it should be something else, but it works for me.
return new Result(yourApp.getIcon().bitmap, Picasso.LoadedFrom.DISK);
}
}
// When you want to show the icon
Picasso picasso = Picasso.Builder(context)
.addRequestHandler(new AppIconRequestHandler())
.build()
picasso.load(packageName)
.placeholder(placeholderIcon)
.into(imageView)
Don't forget to scale app icons, by the way! You can't rely on them to be small images and you may end up using a lot more ram than you need.
This one is using the Picasso library.
String url = "some url to your image";
ImageView thumbnail = (ImageView) findViewById(R.id.thumbnail);
Picasso.with(context).load(url).into(thumbnail);

Image flickering in imageView when list is scrolled or new image is downloaded in new row

I have gone through many questions similar to mine of images flickering problem.
I am not able to correct it. Being a beginner,I am not able to understand what to do.
Here is my code.. where I set thumbnail for a image.
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
new AsyncTask<String, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(String... params) {
Bitmap result = mBitmapCache.get(uri.toString());
if (result == null)
return getThumbnail(contentResolver, uri);
else
return result;
}
#Override
protected void onPostExecute(Bitmap result) {
if (uri != null && result != null) {
// Log.d(TAG, "setThumbnail result not null");
// Log.d(TAG, "uri= "+uri);
// Log.d(TAG, "aHolder.mMediaUri= "+aHolder.mMediaUri);
mBitmapCache.put(uri.toString(), result);
// confirm the holder is still paired to this uri
if (!uri.equals(aHolder.mMediaUri)) {
return;
}
// set the thumbnail
ImageLoader imageLoader=ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(getContext()));
DisplayImageOptions options = new DisplayImageOptions.Builder()
// .showImageForEmptyUri(R.drawable.ic_empty)
// .showImageOnFail(R.drawable.ic_error)
.resetViewBeforeLoading(true).cacheOnDisk(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
.cacheInMemory(true)
.displayer(new FadeInBitmapDisplayer(300)).build();
imageLoader.displayImage(uri.toString(), aHolder.mMediaThumbnail, options);
// aHolder.mMediaThumbnail.setImageBitmap(result);
} else {
// Log.d(TAG, "setThumbnail result null");
}
}
}.execute();
}
In ListView view is added when it is required (See https://stackoverflow.com/a/14108676/2274724). So your item will create when you call notifyDataSetChange() or scroll your list.
So whenever your view is created your image will load again from cache which results into flickering. There is a solution :
First Load image in background thread (Either from network or assets) then create a bitmap cache as u did but instead of getting image using AsyncTask get Image directly if it exist in bitmap cache (But this is again not a good way because it will stop flickering but list scroll will not be smooth when size is large).
I will Suggest use UniversalImageLoader. They implemented memory cache in much better way.
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
ImageLoader.getInstance().displayImage(
uri.toString(),
aHolder.mMediaThumbnail, getDisplayOption());
}
// Add or remove option according to your requirement
private DisplayImageOptions getDisplayOption() {
return new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnLoading(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
.cacheOnDisk(true).resetViewBeforeLoading(true)
.displayer(new RoundedBitmapDisplayer(22))
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
//Put it in your Application file and call it just once.
private void initImageLoader() {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.defaultDisplayImageOptions(getDisplayOption()).build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);
}
Before I was using:
AssetManager
InputStream
BitmapFactory
All of this to get a Bitmap
And finally use imageView.setImageBitmap(bitmap)
Nowadays we have libraries that help loading and caching images.
I have used Picasso for loading images from the web.
But Picasso is available for assets too!
Here is a Kotlin example:
val picassoPrefix = "file:///android_asset"
Picasso.get().load("$picassoPrefix/$assetsPath/$fileName")
.placeholder(R.mipmap.ic_launcher_round)
.into(imageView)
Note:
We can use the fetch method for preloading too.
In my case I don't think it's necessary, since the placeholder is displayed for the first time, and for the next times, the images are displayed immediately without flickering.

Set image loaded from URL as wallpaper

I'm using Picasso in my app and I managed to open the image in a fullscreen view when the user taps it. Now I would like a button which overlays the image and that sets the image as wallpaper.
All images are loaded from URL and stored in a remote server.
I don't know how to achieve this since I'm a veeeery beginner. Can someone help me?
Thanks.
Use this code in button onclicklistener to set image as wallpaper
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
WallpaperManager wpm = WallpaperManager.getInstance(getApplicationContext());
wpm.suggestDesiredDimensions(width, height);
InputStream ins = null;
try {
ins = new URL(Imageurl).openStream();
wpm.setStream(ins);
Toast.makeText(ImageViewerActivity.this, "successfully set", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
use ImageLoader instead:
DisplayImageOptions options = new DisplayImageOptions.Builder()
.bitmapConfig(Bitmap.Config.ALPHA_8)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
ISolaceContext.getAppContext())
.discCacheExtraOptions(20, 20, CompressFormat.JPEG, 100, null)
.defaultDisplayImageOptions(Media.options).build();
ImageLoader.getInstance().init(config);
ImageLoader loader = ImageLoader.getInstance();
loader.loadImage(url, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
// Now you have the image in your hands as a Bitmap(called: loadedImage) and Now you can do whatever you want with it
stream.close();
stream = null;
}
});
loader.clearDiscCache();
loader.clearMemoryCache();
Now you can use the previously generated Bitmap as a background.converting bitmap to drawable.

Categories

Resources