I have a variable Bitmap image. I have imageButton in my fragment. I can change image of imageButton with Glide.with().load().into(). But I want not to just change image but to save it into Bitmap variable so I can use it for some other task. I tried this
Bitmap image = Glide.with(getContext()).asBitmap().load(imagePath).submit().get();
imageButton.setImageBitmap(image);
But image of imageButton does not change. What's wrong with first line then? Because I am pretty sure that problem is there but don't understand yet what is exactly wrong.
A solution is to do
Bitmap image = BitmapFactory.
decodeStream(getContext().
getContentResolver().
openInputStream(selectedImage));
imageButton.setImageBitmap(image);
Where selectedImage is Uri selectedImage = data.getData() of onActivityResult method, but it will be total mess because of size of bitmap, so we have to use createScaledBitmap, I don't like it. For some reason Bitmap image = BitmapFactory.decodeFile(imagePath) doesn't work, imageButton just becomes tiny grey square, and I didn't find a solution for this.
first of all why are using the imageButton..use imageView it will good than
imagebutton and it will work
I don't know if you should even think about doing this in some serious project but for now it did what needs to be done for me. Earlier I declared private Bitmap jopa.
Glide.with(getContext()).asBitmap().
load(selectedImage).override(500,500).
into(new CustomTarget<Bitmap>()
{
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
imgShare.setImageBitmap(resource);
jopa = ((BitmapDrawable)imgShare.getDrawable()).getBitmap();
}
#Override
public void onLoadCleared(#Nullable Drawable placeholder) {
}
});
Now Bitmap jopa can be used for other tasks. I hope. Tested it to change picture of another imageview, it worked, so I'll pray it will work further. Full onActivityResult code here. Don't want question to get too messy
Related
I want to blur a portion of bitmap and set into image view. But I am not getting any reference of the same.
Took me 40 seconds to find the solution in stackoverflow, Please use search :)
Use the blur from here:
https://stackoverflow.com/a/10028267/5618671
(Make sure to +1 Yahel, the user that posted the blur solution)
Get your Bitmap (can get it from your existing imageView), Call the fast blur when imageView has been clicked, and set the imageView with the new blurred Bitmap :
example
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//GET BITMAP FROM IMAGEVIEW
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmapFromImageView = drawable.getBitmap();
Bitmap blurredBitmap = fastblur(bitmapFromImageView, BITMAP_SCALE, BLUR_RADIUS)
imageView.setImageBitmap(blurredBitmap);
}
});
P.S Make sure imageview is declared final:
final ImageView imageView;
I use Glide to load my image. I need to modify my image with a SimpleTarget callback, however when the image loaded to my list, and I scroll the list shows first always an other image, and than animate the right image after 1 second to the place. Without image modification and SimpleTarget everything works just fine. Here is my code.
#BindingAdapter("imageSrc")
public static void setImage(ImageView imageView, String url) {
Glide.with(imageView.getContext()).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
//the bitmap modified here
imageView.setImageBitmap(bmp);
}
});
}
is there any solution to avoid the flickering?
I'm trying to show images from a URL in a ImageSwitcher. I've tried with:
myImageSwitcher.setImageURI(Uri.parse("http://miurl.com/images/foto01.jpg"));
but it said me this "error":
I/System.outīš resolveUri failed on bad bitmap uri: http://miurl.com/images/foto01.jpg
Thanks
I know it is late but because I found a better solution for this, would love to share it with all :)
I had to look at the source code of the default ImageSwitcher and know how it works. Whenever we use ImageSwitcher we set a ViewFactory to it. This ViewFactory creates Views which are then used in the ImageSwitcher. Usually we create an ImageView in the ViewFactory. This ImageView is then used in the ImageSwitcher class to draw the view with the image source specified. Below is the setImageResource() method of the ImageSwitcher class.
public void setImageResource(#DrawableRes int resid){
ImageView image = (ImageView)this.getNextView();
image.setImageResource(resid);
showNext();
}
Let's focus on the first and second line of the method.
ImageView image = (ImageView)this.getNextView();
image.setImageResource(resid);
this.getNextView() gets the view from the ViewFactory and casts the view into an ImageView. And then, the Drawable resource is set to it.
Solution
Now, with these information, let's get to the solution! I'm using Volley's NetworkImageView , but you can use Picasso or Glide too! You just have to change the code a bit.
We need to create a custom ImageSwitcher. Here's my code
MyImageSwitcher.java
public class MyImageSwitcher extends ImageSwitcher {
public MyImageSwitcher(Context context) {
super(context);
}
public MyImageSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setImageUrl(String url) {
NetworkImageView image = (NetworkImageView) this.getNextView();
image.setImageUrl(url, AppController.getInstance().getImageLoader());
showNext();
}
}
Notice the setImageUrl() method. We cast the view we get from getNextView() to a NetworkImageView and set the Url to it. If you want to use Picasso, then just cast it into an ImageView and then use Picasso as it needs to be used.
Activity
MyImageSwitcher imageSwitcher = (MyImageSwitcher) findViewById(R.id.imageSwitcher);
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
public View makeView() {
NetworkImageView myView = new NetworkImageView(getApplicationContext());
myView.setScaleType(ImageView.ScaleType.CENTER_CROP);
myView.setLayoutParams(new ImageSwitcher.LayoutParams(imageSwitcher.getLayoutParams()));
return myView;
}
});
If you want to use Picasso, then just use an ImageView.
Layout
<xyz.farhanfarooqui.loadingimages.MyImageSwitcher
android:id="#+id/imageSwitcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
AndroidManifest.xml
Don't forget to include android.permission.INTERNET to your AndroidManifest.xml
Done!
Whenever you want to change the image, do it this way,
imageSwitcher.setImageUrl("http://miurl.com/images/foto01.jpg");
I've solucionated this problem using SliderLayot (https://github.com/daimajia/AndroidImageSlider), but I'll try to do with ImageSwitcher too.
I was trying to achieve the same thing when I landed here. I know it's and old question, but since I don't see an answer, I'll tell you the solution that worked for me.
First of all, I downloaded the image/s that I wanted to show in the imageswitcher and return them as a Bitmap using this code:
InputStream in = new java.net.URL(url).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
Then I set the bitmap in the imageswitcher using imageSwitcher.setImageDrawable(new BitmapDrawable(getResources(), bitmap)).
To use java.net.URL(url).openStream(), you'll need to add <uses-permission android:name="android.permission.INTERNET"> to your AndroidManifest.xmlfile.
Have in mind that you could change the download code to make it better (checking for timeouts for example), but this is just a basic solutions to start from.
Another thing about what you were using, I think you can't use setImageURI() to set an internet resource in your ImageSwitcher. Acording to this post, this method is only for content URIs particular to the Android platform (Note that they are talking about an ImageView in that post, but I think the same goes to this case).
I am trying to insert a generic loading circle as placeholder while an image is being loaded with an image loader library like Glide or Picasso.
I cannot for the life of me find out how you are supposed to create a rotating drawable from xml.
I tried using an AnimationDrawable in XML by creating an animation-list, but it doesn't even show up (not even static).
I just want to have a simple circle that spins all by itself, all in an xml drawable, so I can pass the id as placeholder to my image loader. If that is not possible please tell me now, so I can save a lot of research :)
EDIT: Some code to make it more clear, I need a spinning drawable for this Glide command:
Glide.with(context)
.load(imageUrl)
.into(imageView)
.placeHolder(R.drawable.spinning_loading_placeholder);
While the image is being loaded a placeholder drawable will be shown where the image will later be. I need a drawable that spins itself.
You can add a ProgressBar element to your layout XML, and then display/hide this element as needed. The ProgressBar View is built in and already animated, no custom AnimationDrawable required.
You can use something like this:
Glide.with(mContext).load(imageUrl).asBitmap().centerCrop().into(new BitmapImageViewTarget(vh.avatarImageView) {
#Override
public void onLoadStarted(Drawable placeholder) {
vh.avatarImageView.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_placeholder));
}
#Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
vh.avatarImageView.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_failed_download));
}
#Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(mContext.getResources(), resource);
circularBitmapDrawable.setCircular(true);
vh.avatarImageView.setImageDrawable(circularBitmapDrawable);
}
});
Recently, I started using Google ImageWorker class for loading bitmaps on a background thread. This class handles everything, including putting the bitmaps in the ImageView. Google talks about this class (and it's helper classes for Image manipulation and caching) here: http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
The ImageView(s) in my case are parts of list items in a ListView. Here's the interesting part of getView on my ArrayAdapter:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView == null ? inflater.inflate(R.layout.nodelist_item, null) : convertView;
NodeHolder holder = getHolder(view);
Node node = mList.get(position);
holder.txtTitle.setText(node.Title);
//Setting the rest of the different fields ...
//And finally loading the image
if(node.hasArt())
worker.loadImage(node.ImageID, holder.imgIcon);
}
The entire getView method can be seen here: http://pastebin.com/CJbtVfij
The worker object is a very simple implementation of the ImageWorker:
public class NodeArtWorker extends ImageWorker {
protected int width;
protected int height;
public NodeArtWorker(Context context) {
super(context);
addImageCache(context);
//Code for getting the approximate width and height of the ImageView, in order to scale to save memory.
}
#Override
protected Bitmap processBitmap(Object data) {
Bitmap b = getBitmap(data);
if(b == null) return null;
return Utils.resizeBitmap(b, width, height);
}
protected Bitmap getBitmap(Object data) {
//Downloads the bitmap from a server, and returns it.
}
}
This works very well, and the performance is much better now than before. However, if I change the ImageID on some of the items in the list, and call adapter.notifyDataSetChanged() to rebuild the view (and thereby start loading new bitmaps), I get a RuntimeException:
0 java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#41adf448
1 at android.graphics.Canvas.throwIfRecycled(Canvas.java:1058)
2 at android.graphics.Canvas.drawBitmap(Canvas.java:1159)
3 at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:440)
4 at android.widget.ImageView.onDraw(ImageView.java:1025)
5 at android.view.View.draw(View.java:14126)
The full stacktrace can be seen in the following pastebin entry, but is probably uninteresting, as it is the typical Android view hierarchy redraw stacktrace: http://pastebin.com/DsWcidqw
I get that the Bitmaps are being recycled, but I don't understand exactly where and what can be done about it. As my code comes directly from Google, and is, as far as I understand, the recommended way of doing this, I am very confused.
On Android, Bitmaps can be recycled to be later re-used (much faster than re-creating a Bitmap).
The Bitmap#recycle()method will flag the Bitmap as recycled.
So if you try to set such a recycled bitmap to an ImageView or draw it on a Canvas, you will end up with this exception:
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap
The official demo that you linked on your question is dealing with recycled Bitmaps.
It uses a dedicated method hasValidBitmap() and checks the Bitmap#isRecycled() value:
private synchronized boolean hasValidBitmap() {
Bitmap bitmap = getBitmap();
return bitmap != null && !bitmap.isRecycled();
}
So you need to do the same. When you're searching on your cache for a Bitmap, before applying it to an ImageView, check if it's recycled or not. If it's not you can directly set it, otherwise, you need to update the Bitmap.
To create a new Bitmap from a recycled Bitmap, you can use the Bitmap::createBitmap(Bitmap) method.
You can find more details on this page.
i think this is not the ImageWorker class bug, this is
com.mobeta.android.dslv.DragSortListView.dispatchDraw(DragSortListView.java:797)
issue. so in order to see my answer is correct or not just remove that library and see if it works or not. after that i think the best solutions are:
1- not use that library.
2- report issue on github.
3- solve it by your own and debugge it.
4- or you can set null for image holder bitmap
holder.imgIcon.setBitmapDrawble(null);
and then call worker.loadImage.