Handle corrupt images from JSON in android - android

Iam getting some image URLs in my JSON which I parse and show in my image view. So if the Url is null, I show a default image. But in some cases the Urls are specified but the images are corrupted. In this case nothing displays in the ImageView only a white space shows. Is there any way I can handle this scenario.
Any help will be useful.

You can use ImageLoader to check this case. Example:
private ImageLoader imageLoader = new ImageLoader();
private ImageView Iv;
private String URL =null;
private DisplayImageOptions mDio;
URL = "URL you get from your JSON";
if (URL != null) {
imageLoader.displayImage(URL, Iv, mDio, new SimpleImageLoadingListener() {
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
// check corrupt images on here
view.setImageResource(R.drawable.iv_fail)
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
view.setImageBitmap(loadedImage);
}
}
}, new ImageLoadingProgressListener() {
#Override
public void onProgressUpdate(String imageUri, View view, int current,
int total) {
}
});
} else Iv.setImageResource(R.drawable.iv_default);
Hope this helps

Use picasso bro
A very easy image handling library for android
Picasso supports both download and error placeholders as optional features.
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView);
http://square.github.io/picasso/
and yes,its that easy

The Best way to do it easily is to use proper lib - Use picasso or UIL or something else. Advantages is that this libs are well maintained and is stable. Your empty image will be treated as an error and default will be shown

Related

ListView with Image Loader not loading efficienty

My ListView is not scrolling smoothly. It's like it always reloads the image from API. I want to have it scrolling smoothly.
The library that I am using to load the images is Universal Image Loader.
JAVA
String url = MainActivity.IMAGE_URL + "postid=" + model.get(position).getId();
loader.loadImage(url, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
holder.image.setVisibility(View.VISIBLE);
holder.image.setImageBitmap(loadedImage);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
holder.image.setVisibility(View.GONE);
holder.image.setImageBitmap(null);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
holder.image.setVisibility(View.GONE);
holder.image.setImageBitmap(null);
}
});
I am using this code after trying Universal ImageLoader, Picasso and Glide library, And it is fastest for me using RecyclerView.
Uri uri = Uri.fromFile(new File(path));
Picasso.with(mContext)
.load(URL_OF_IMAGE)
.error(R.drawable.blank)
.config(Bitmap.Config.RGB_565)
.resizeDimen(R.dimen.d50dp, R.dimen.d50dp)
.centerCrop()
.into(holder.imageview);
Check this owesome link that shows difference with respect to load time and memory in detail,
https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
You can extend your DisplayImageOptions with extra caching capabilities.
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.avatar)
.showImageOnFail(R.drawable.avatar)
.cacheInMemory(true) // default is false
.cacheOnDisk(true) // default is false
.build();
Source: DisplayImageOptions
You can also change default ImageLoaderConfiguration and change cache size or increase thread priority (if you like). Note that you only need to set this configuration once in you application unlike DisplayImageOptions. See: ImageLoaderConfiguration

Picasso loads image with triangle in corner of image

I'm using picasso library for loading images from server into my application. my problem is when image loaded it has a triangle in top-left corner of image with color(like blue,green,red).
this is my code for loading image:
public static void loadDynamicImage(final String url, final Context context, final ImageView imageView, final int width, final int height){
Picasso.with(context).load(url)
.networkPolicy(NetworkPolicy.OFFLINE)
.resize(width,height)
.onlyScaleDown()
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(context).load(url).resize(width,height).onlyScaleDown().into(imageView);
}
});
}
the image shown is :
You have enabled debug indicators on your Picasso instance (see official website). Look for setIndicatorsEnabled(true) in your code and remove it.
You have setIndicatorsEnabled set to true
Picasso picasso = Picasso.with(this);
picasso.setIndicatorsEnabled(false); //Or remove picasso.setIndicatorsEnabled(true);
Check this: Is there any way from which we can detect images are loading from cache in picasso?

Imageloader inside for loop in android

I need to loop the image load Google map marker with images. So, I am using custom marker( there will more than 50 different marker images). I am using Universal Image loader for loading the image on Image view. Once the image is loaded on the Image view I am converting that view into marker.
My problem is ImageLoadingListener is not getting looped. But if I am placing the breakpoint then It is working fine.
final View marker = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_marker_layout, null);
final RoundedImageView imv_Logo = (RoundedImageView) marker.findViewById(R.id.imv_size);
bitmapArray.clear();
for (int i = 0; i < list_image_url.size(); i++) {
imageLoader.displayImage(list_image_url.get(i), imv_Logo, options,
new ImageLoadingListener() {
#Override
public void onLoadingStarted(String arg0, View arg1) {
}
#Override
public void onLoadingFailed(String arg0, View arg1,
FailReason arg2) {
imv_Logo.setImageDrawable(getResources().getDrawable(R.drawable.image_not_found));
bitmapArray.add(createDrawableFromView(Establishment.this, marker));
if (bitmapArray.size() == list_image_url.size()) {
loadmarker(progressDialog);
}
}
#Override
public void onLoadingComplete(String arg0, View arg1,
Bitmap arg2) {
bitmapArray.add(createDrawableFromView(Establishment.this, marker));
if (bitmapArray.size() == list_image_url.size()) {
loadmarker(progressDialog);
}
}
#Override
public void onLoadingCancelled(String arg0, View arg1) {
}
});
}
Could any one help me on this?
I can't guarantee it, but I guess the problem is the following. When you tell the ImageLoader to load an image into an ImageView, it will keep an internal HashMap to track which image will be displayed in which ImageView. What you are actually doing here, is asking the ImageLoader to download different images but to display them in the same ImageView.
imageLoader.displayImage(list_image_url.get(i), imv_Logo,....
So each time you call displayImage, it will actually update the Map and I guess that ImageLoader is smart enough to cancel previous downloads. So in the end, you only download one image.
While in debug mode, the download will have time to occur between twi calls to displayImage, therefore you will see multiple calls to onLoadingComplete.
What would make sense is to have several ImageViews.

Universal Image Loader cache images

I have trouble finding the right workflow to load images into cache.
What I want to do:
Show Progress bar
Get data from REST service and load it into SQLite database
Some objects contain urls in JSON > load these images in cache so
they are quickly loaded when needed
Dismiss Progress bar
I have all the data loaded from rest and stored in a DB,
but I'm new to caching images.
What I go so far:
- Inserted Universal Image Loader into my project
(https://github.com/nostra13/Android-Universal-Image-Loader)
- I tried
imageLoader.loadImage(url of an image, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
super.onLoadingStarted(imageUri, view);
//notify me the image started loading
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
//notify me the image is loaded
}
}
But when I check:
int size = MemoryCacheUtils.findCachedBitmapsForImageUri(url from that image, ImageLoader.getInstance().getMemoryCache()).size();
//show me the size
it's always zero.
My question is the following: am I going in the right direction or do I need to fix this someother way?
I found a better solution: ShutterBug (Android alternative for SDWebImage for iOs). It's easy to add urls to the ShutterbugManager and when I want to fill an ImageView (FetchableImageView in Shutterbug) with an image, it grabs the image from cache.

Universal Image Loader get original image size

I am using the Android-Universal-Image-Loader library to loading/caching remote images, and have been digging through the source for quite a while trying to find a way to retrieve the original image size (width and height) for my ImageLoadingListener.
The sample code below is just give you an idea of what I'm trying to do.
protected class ViaImageLoadingListener implements ImageLoadingListener {
final SelectableImageView selectableImageView ;
protected ViaImageLoadingListener(SelectableImageView selectableImageView) {
this.selectableImageView = selectableImageView;
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
selectableImageView.setImageBitmap(loadedImage);
// loadedImage.getWeight() will not return the original
// dimensions of the image if it has been scaled down
selectableImageView.setOriginalImageSize(width, height);
selectableImageView.invalidate();
}
I have tried extending the ImageDecoder class and the ImageLoader class to find a round-about way to linking the decoder (from which I can get the original image size in the #prepareDecodingOptions method) to my custom ImageLoadingListener. But the configuration object is private and the fields (including the decoder) are inaccessible from subclasses (and feels like an overly hacky way of solving the problem anyways).
Have I overlooked a simple "built-in" way of getting the original image size without losing the benefit of the UIL's scaling/memory management?
There is no way to pass original image size from ImageDecoder to listener through params.
I think the solution for you is following.
Extend BaseImageDecoder and create map in it for keeping image sizes:
Map<String, ImageSize> urlToSizeMap = new ConcurrentHashMap<String, ImageSize>();
Then override defineImageSizeAndRotation(...):
protected ImageFileInfo defineImageSizeAndRotation(InputStream imageStream, String imageUri) throws IOException {
ImageFileInfo info = super.defineImageSizeAndRotation(imageStream, imageUri);
urlToSizeMap.put(imageUri, info.imageSize); // Remember original image size for image URI
return info;
}
Note: info.imageSize won't compile because imageSize isn't visible. I'll fix it in next version (1.8.5) but you can use reflection for now.
Set this decoder into configuration and keep reference to this decoder anywhere (or you can make urlToSizeMap static to access from listener).
Then in your listener:
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
selectableImageView.setImageBitmap(loadedImage);
ImageSize imageSize = decoder.urlToSizeMap.get(imageUri);
selectableImageView.setOriginalImageSize(imageSize.getWidth(), imageSize.getHeight());
selectableImageView.invalidate();
}
It seems that you do not have to implement own ImageLoadingListener if you want to get original size of loaded image. I use loadImage method and it seems recieved bitmap has origin sizes.
UIL v1.8.6
loader.loadImage(pin_url, option, new SimpleImageLoadingListener() {
#Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
showErrorLayout();
}
#Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
// width - device width
// height - OpenGl maxTextureSize
if (width < loadedImage.getWidth() || height < loadedImage.getHeight()) {
// handle scaling
}
iv.setImageBitmap(loadedImage);
}
});

Categories

Resources