I'm writing a custom gallery using UIL library and for testing the performance, I've modified ImagePagerActivity(of example code) to load images from sdcard. Everything works fine but loading is way too slow, sometimes it even takes 5 seconds to load a single image. However if I use in-built gallery, its way faster and loads more images in milliseconds. Here is the snippet of modified onCreate
File file = new File(Environment.getExternalStorageDirectory(), "dcim/100MEDIA/");
File[] images = file.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
return filename.toLowerCase(Locale.US).endsWith(".jpg");
}
});
String[] imageUrls = new String[images.length];
for (int a = 0; a < imageUrls.length; a++)
imageUrls[a] = "file://" + images[a].getAbsolutePath();
options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error).resetViewBeforeLoading(true).cacheOnDisc(true)
.cacheInMemory(true).imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.defaultDisplayImageOptions(options).discCacheExtraOptions(800, 800, CompressFormat.PNG, 0, null)
.build();
ImageLoader.getInstance().init(config);
and little modified ImagePagerAdapter
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
Toast.makeText(ImagePagerActivity.this, loadedImage.getWidth() + " x " + loadedImage.getHeight(),
Toast.LENGTH_SHORT).show();
}
Usually common image dimension is 2592x1552
UIL 1.8.6
Android version : 4.0.3
Others are just same as example code
What does your ImageLoaderConfiguration look like? What threadPriority do you set it? Also, ImageScaleType.EXACTLY creates another bitmap so this will add load time. For my ImageLoaderConfiguration I have threadPriority set to Thread.MAX_PRIORITY and threadPoolSize set to 5:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext()).threadPriority(Thread.MAX_PRIORITY)
.memoryCacheSize(memoryCacheSize)
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory().threadPoolSize(5)
.discCacheFileNameGenerator(new MyFileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)// .enableLogging()
.build();
Related
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);
Use two biblotecas in my application, Universal Image Loader and another that uses the library picasso,
the picasso library, records the image in the cache /cache/picasso-cache/ and the names are generated with the MD5 URL.
To separate the cache Universal Image Loader, I write to /cache/LazyLoad/ and names generated with the item ID.
My code of configuration Universal Image Loader
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheOnDisk(true)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300))
.build();
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(getApplicationContext());
config.defaultDisplayImageOptions(defaultOptions);
config.memoryCache(new WeakMemoryCache());
config.threadPriority(Thread.NORM_PRIORITY - 2);
config.denyCacheImageMultipleSizesInMemory();
config.tasksProcessingOrder(QueueProcessingType.LIFO);
config.writeDebugLogs(); // for debug
FileNameGenerator fileNameGenerator = new FileNameGenerator() {
#Override
public String generate(String imageUri) {
String fileName = imageUri.substring(imageUri.lastIndexOf('/')+1, imageUri.length());
String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExtension;
}
};
String pathCache = Globais.getCacheDirImageLazyLoad(mContext); //returns StorageUtils.getCacheDirectory(context, false).getAbsolutePath() + "/lazyload";
File f = new File(pathCache);
if (!f.exists())
f.mkdirs();
DiskCache diskCache = new UnlimitedDiskCache(f, null, fileNameGenerator);
config.diskCache(diskCache);
config.diskCacheFileNameGenerator(fileNameGenerator);
ImageLoader.getInstance().init(config.build());
Problem that after I started using the component that uses the picasso, began to double the cache, ALL images that use the Universal Image Loader, also appear in Picasso's cache.
How can I fix this ???
Anyone have any idea?
I am using Universal Image Loader lib in my app and caching the images to my sd card. The images are being saved very well, and i can see them using any file explorer in my mobile.
But the images are not shown in gallery.
Is there anyway to make them appear in gallery images too.
EDITE :
File filePath = Environment.getExternalStorageDirectory();
String phNumber[] = Constacts.contactJID.split("#");
String dir = "/Image Messages/"+phNumber[0];
File myCacheDir = new File(filePath, dir);
if(!(myCacheDir .exists())){
myCacheDir .mkdirs();
}
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity())
.defaultDisplayImageOptions(defaultOptions)
.memoryCache(new WeakMemoryCache())
.diskCacheSize(100 * 1024 * 1024)
.diskCache(new UnlimitedDiscCache(myCacheDir , myCacheDir , new MyFileNameGenerator() ))
.build();
Edited (2nd):
public class MyFileNameGenerator extends Md5FileNameGenerator {
#Override
public String generate(String imageUri) {
return super.generate(imageUri)+".jpg";
}
}
Is it possible to catch offline using universal image loader?
If possible, how to use it?
Using configs?
How To Set Download Directory manually?
out of memory erroron load huge images :
my codes :
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).cacheInMemory(true)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(G.appConfigs.context)
.defaultDisplayImageOptions(defaultOptions)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
.diskCacheExtraOptions(480, 800, null)
.memoryCache(new WeakMemoryCache())
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.discCacheSize(300 * 1024 * 1024)
.build();
ImageLoader.getInstance().init(config);
// END - UNIVERSAL IMAGE LOADER SETUP
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.no_pic)
.showImageOnFail(R.drawable.load_failed)
.showImageOnLoading(R.drawable.img_thumb).build();
//download and display image from url
imageLoader.displayImage(imgURL, img, options);
how to resolve it ?
You can use the ImageLoaderConfiguration.Builder class to customize disk caching. This includes the methods:
diskCacheExtraOptions()
diskCacheSize() (in bytes).
diskCacheFileCount()
diskCacheFileNameGenerator()
and some others.
Or you can just use diskCache(DiskCache) to provide a custom class for implementing offline caching.
From the example in the Configuration section of the wiki:
File cacheDir = StorageUtils.getCacheDirectory(context);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
.diskCacheExtraOptions(480, 800, null)
.taskExecutor(...)
.taskExecutorForCachedImages(...)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.memoryCacheSizePercentage(13) // default
.diskCache(new UnlimitedDiscCache(cacheDir)) // default
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.imageDecoder(new BaseImageDecoder()) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs()
.build();
But if you restart your device or clean your cache by anyway it will not work offline as the cached files will be deleted.
To Show offline images you have to download images on sd-card to a specific folder and have to pick from there in case on offline.
Don't Know much about such lib. but you can use the following method to download your images.
Just Call it from an Async. Task and pass your url.
private File root = Environment.getExternalStorageDirectory();
private File dir = new File(root.getAbsolutePath() + "/ImageFolder");
private void downloadFile(String url) throws Exception {
URL ur = new URL(url);
String fileName = url.substring(url.lastIndexOf("/") + 1);
File file = new File(dir, fileName);
URLConnection uconn = ur.openConnection();
InputStream is = uconn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while ((current = bufferinstream.read()) != -1) {
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
}
Universal Image Loader is one perfect library to load async your images.
You can use #matiash answer to setup library configuration and then with
ImageLoader.getInstance().init(config);
you can apply them to the ImageLoader instance.
After that if you have internet connection at the begin of your application, Universal Image Loader will download and cache all your images, on the places where you use loading of those images with Universal Image Loader library. The next time when you load same images, Universal Image Loader will get them from the cache, which means you don't need to have any internet connection(can work offline).
The problem came when somebody is installing your application and trying to start using it for the first time, and if he doesn't have internet connection. Then Universal Image Loader will try to load your images from the web server and cache them to the storage, but it will fail because you don't have internet connection. That's why Universal Image Loader has a class like DisplayImageOptions :
new DisplayImageOptions.Builder()
which allow you to setup what should happen when there is a problem with loading your images. You can use for this purpose methods like:
.showImageOnLoading(R.drawable.default_image)
.showImageForEmptyUri(R.drawable.default_image)
.showImageOnFail(R.drawable.default_image)
Here is an example how you can use it:
DisplayImageOptions imageOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(getImageLoaderDefaultImage())
.showImageForEmptyUri(getImageLoaderDefaultImage())
.showImageOnFail(getImageLoaderDefaultImage())
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.build();
Method getImageLoaderDefaultImage():
private int getImageLoaderDefaultImage(){ return R.drawable.default_img;}
And here is how to use Image Loader when you want to load image:
ImageLoader.getInstance().displayImage("image url", myImageView,imageOptions);
If you are using Xamarin : Add Below code in OnCreateView or similar is available in Java also.
DisplayImageOptions options = new DisplayImageOptions.Builder().CacheInMemory(true).CacheOnDisk(true).Build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this.Context).DefaultDisplayImageOptions(options).Build();
ImageLoader.Instance.Init(config);
Add below line of code, when loading image
ImageLoader imageLoader = ImageLoader.Instance;
imageLoader.DisplayImage(imgURL, imageSource);
I do exactly what this guy suggests which is exactly the same as the creator of the Universal Image Loader, but I still get this error:
URI = assets://NMF0002_007.jpg
resolveUri failed on bad bitmap uri: NMF0002_007.jpg
What should I look for to ensure that the images are recognised?
I use it like this:
//get the file name
String fileName = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.FIELD_RESOURCE));
String imageUri = "assets://";
Log.d(TAG, "URI = " + imageUri + fileName);
ImageLoader.getInstance().displayImage(imageUri+fileName, holder.iv_details_resource);
This is my configuration:
//Get the imageloader.
ImageLoader imageLoader = ImageLoader.getInstance();
//Create image options.
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
//Create a config with those options.
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(options)
.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75)
.build();
//Initialise the imageloader.
imageLoader.init(config);
What am I doing wrong or missing?
Solution - I was looking for .jpg and my file extension was .JPG
If NOSTRA can post some clever things to be on the lookout for I'll mark your answer as an official answer to my silliness.