I want get a bitmap use Picasso but fail - android

I am tried this code, but not getting the desired output.
Picasso.with(getApplicationContext()).load(mPicList.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
zoomImageView.setImageBitmap(bitmap);
Logger.getInstance().v("qw", "ViewPagerAdapter.134.onBitmapLoaded.");
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Logger.getInstance().v("qw", "ViewPagerAdapter.139.onBitmapFailed.");
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Logger.getInstance().v("qw", "ViewPagerAdapter.144.onPrepareLoad.");
}
});
It always print log onPrepareLoad why????

Your problem is that nothing keeps a strong reference to the Target instance so it gets garbage collected.
You can't just call new Target() { ... } because there aren't any strong references to it. You need to store it on a field in a view holder or implement it on a subclass of a view.
See this answer:
https://stackoverflow.com/a/30681395/5476209
this guy explicitly managed garbage collection issue happening in library.

I'm not sure if there is a reason for new Target()... but you can try to use something like this:
Picasso.with(this).load(mPicList.get(position)).into(zoomImageView);
If you are in a Fragment, use getActivity() instead of this.

Related

android picasso .into(new Target() causing method error

We are using the following code to load images into notification .setLargeicon parameter in our android webview app. But unfortunately .into(new Target() { displays the following warning:
Class 'Anonymous class derived from Target' must either be declared abstract or implement abstract method 'value()' in 'Target'. We are at loss as what we should do to solve this issue.
Picasso.get().load("https://mbracecloud.com/appln_enterprise/images/reconnect_feature7.jpg")
.into(new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
notificationBuilder1.setLargeIcon(bitmap);
notificationManager.notify(notification_id, notificationBuilder1.build());
}
#Override
public void onBitmapFailed(final Drawable errorDrawable) {
// Do nothing
}
#Override
public void onPrepareLoad(final Drawable placeHolderDrawable) {
// Do nothing
}
});
Update:
Based on inputs given below, we put the following import:
import com.squareup.picasso.Target;
and tried to load image, but we are encountering a new error:
Class 'Anonymous class derived from Target' must either be declared abstract or implement abstract method 'onBitmapFailed(Exception, Drawable)' in 'Target'
Please help us out on this issue.
Guessing you're importing the wrong Target and specifically the annotation one. Change
import java.lang.annotation.Target;
to
import com.squareup.picasso.Target;
Based on your error onBitmapFailed(Exception, Drawable), you are overriding this method with only Drawable parameter but the Target class wants to override abstract method with Exception and Drawable parameters. So, try replacing onBitmapFailed with the implementation below:
#Override
public void onBitmapFailed(final Exception exception, final Drawable errorDrawable) {
// Do nothing
}

Android fresco lib , apply custom filter

i'm using fresco to display images to my app. Right now i'm trying to apply some filters to my images but the problem is that the filter library only results Bitmap. But the draweeView.setImageBitmap is deprecated.
I also tried with a post processor like this
MeshPostprocessor meshPostprocessor = new MeshPostprocessor();
meshPostprocessor.setFilter(filters.get(0));
draweeView = (SimpleDraweeView) view.findViewById(R.id.filter_image);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(image)
.setPostprocessor(meshPostprocessor)
.setResizeOptions(new ResizeOptions(100, 100))
.build();
PipelineDraweeController controller = (PipelineDraweeController)
Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(draweeView.getController())
.build();
draweeView.setController(controller);
and here is the PostProcessor
public static class MeshPostprocessor extends BaseRepeatedPostProcessor {
private AbstractConfig.ImageFilterInterface filter;
public void setFilter(AbstractConfig.ImageFilterInterface filter) {
this.filter = filter;
update();
}
#Override
public String getName() {
return "meshPostprocessor";
}
#Override
public void process(Bitmap bitmap) {
bitmap = filter.renderImage(bitmap);
}
}
so when I click on a filter i just run this
meshPostprocessor.setFilter(colorFilterConfig.get(position));
I tried with the debugger, the code goes through all the methods (setFilter , process etc..) but the image is not changing at all...
What am i missing?
I think you don't need a BaseRepeatedPostProcessor in your case.
A normal BasePostProcessor should be sufficient here.
However, the issue seems to be your custom filter:
#Override
public void process(Bitmap bitmap) {
bitmap = filter.renderImage(bitmap);
}
I suppose it returns a different Bitmap? This does not work in Java / for Fresco.
If your filter can do the processing in place, you can use process(Bitmap bitmap) and directly modify the given bitmap (e.g. bitmap.setPixel(...)).
If you cannot do it in place, you can override process(Bitmap destBitmap, Bitmap sourceBitmap) instead and modify destBitmap.
If your bitmap changes it's size, you can override CloseableReference<Bitmap> process(Bitmap sourceBitmap, PlatformBitmapFactory bitmapFactory). However, in this case make sure to actually use the provided bitmapFactory to create the new bitmap to be efficient.
For more information, take a look at http://frescolib.org/docs/modifying-image.html for more information or check out the JavaDoc for BasePostprocessor.
ok so the way I solved this is by adding a super call on the process like this
#Override
public void process(Bitmap dest, Bitmap source) {
Bitmap filtered = filter.renderImage(source, intensity);
super.process(dest, filtered);
}
i didn't noticed that you have to call super in order for the changes to have effect.

Set background resource using Picasso

I know Picasso is an awesome library to play with images.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
with this code i can load an image to an image view.
But is it possible to set a background resource , using Picasso ?
The Javadoc for Picasso's RequestCreator class has the following example:
public class ProfileView extends FrameLayout implements Target {
#Override
public void onBitmapLoaded(Bitmap bitmap, LoadedFrom from) {
setBackgroundDrawable(new BitmapDrawable(bitmap));
}
#Override public void onBitmapFailed() {
setBackgroundResource(R.drawable.profile_error);
}
}
I just had a work around with the Picasso library, I was attempting to set the image as a background as well.
Picasso library made it very easy to do this, there is method by name "FIT()" which will do this job for you.
The one magic line from Picasso is
Picasso.with(context).load(mImageURLS.get(position))
.fit().placeholder(R.drawable.rtrt).into(mImageDownloader);
.fit() does the trick, thanks.

Use of Target in Picasso on Adapter

Im having big troubles using a Target inside an adapter. Im confused about the documentation on the code
Objects implementing this class must have a working implementation of
{#link #equals(Object)} and {#link #hashCode()} for proper storage internally. Instances of this
interface will also be compared to determine if view recycling is occurring. It is recommended
that you add this interface directly on to a custom view type when using in an adapter to ensure
correct recycling behavior.
Im trying to use the Target in this way:
class CustomTarget implements Target {
private ImageView imageView;
public CustomTarget(ImageView imageView) {
this.imageView = imageView;
}
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
imageView.setImageDrawable(new RoundedAvatarDrawable(bitmap));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
imageView.setImageDrawable(errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
imageView.setImageDrawable(placeHolderDrawable);
}
#Override
public boolean equals(Object o) {
return imageView.equals(o);
}
#Override
public int hashCode() {
return imageView.hashCode();
}
}
#Override
public View getView(int position, View v, ViewGroup parent) {
....
RoundedAvatarDrawable r = new RoundedAvatarDrawable(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_avatar_seahorse));
ImageCacheController.with(mContext).getPicasso().load(member.getPicture_url()).resize(100, 100).centerCrop().placeholder(r).error(r).into(new CustomTarget(viewHolder.ivAvatar));
....
}
It's doesn't work and the images change between each others randomly
You don't show your whole getView function, so without knowing how you use the viewHandler, here's my take on what's going on:
Your problem is that you're creating a new CustomTarget every time getView gets called. You are going against the point of having a Target object. Let me elaborate.
When a new download request is made, previous requests to the same target get stopped or don't result in a call to the Target's callbacks. (so if the Target gets reused for a different row in a list it doesn't get both rows' images).
You are using a new object for each request, effectively hinting Picasso that each request is for a different row so to speak. The doc says "Instances of this interface will also be compared to determine if view recycling is occurring", so since each request has a newly created CustomTarget object, no two requests will have the same object and a row recycle won't be detected.
You're also using viewHolder. In this case I think the viewHolder should be extending the Target interface (if you only have 1 image per row). This way everytime you request a download you can use the same object and not create a new one.
You're also delegating the implementation of your CustomTarget to the ImageView's implementation. Make sure that ImageView's equals and hashCode functions fullfill the requirements Picasso asks for.
Some info on how to implement equals and hashCode: What issues should be considered when overriding equals and hashCode in Java?
It seems your equals method is broken. You are comparing an imageview to a custom target. This might fix it:
public boolean equals(Object o) {
if(o instanceof CustomTarget) {
return ((CustomTarget) o).imageView.equals(this.imageView);
}
return super.equals(o);
}

Recycling Entities in AndEngine Generic Pool

I'm using a class that extends GenericPool to handle getting and recycling of sprites. What I'd like to do is have a method in that class to recycle after a certain duration. Something like:
public void recyleIn(Sprite sprite, float durationSeconds) {}
And there's a handy/dandy DelayModifier that seems like the proper way to implement it. So we'd have something like the following:
public void recyleIn(MySprite mySprite, float durationSeconds) {
mySprite.registerEntityModifier(
new DelayModifier(
durationSeconds,
new IEntityModifierListener() {
#Override
public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
}
#Override
public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
recycle(mySprite);
}
}
));
}
Now here's the problem: I can't call the recycle() method or do the recycling right there unless the Sprite is "final". Ordinarily that wouldn't be a problem, I'd just make a "final" deepcopy and use that. But in this case, making a copy defeats the original purpose of recycling in a pool. (E.g., if I'm just going to make a copy anyway, why bother to recycle and use pooling in the first place?)
Any ideas on the proper approach/model for this sort of thing? Thanks in advance.
UPDATE:
Umm.. I just realized I could just use the IEntity parameter in the onModifierFinished() method. (I'm used to ignoring those parameters for some reason.) So I could do something like this within the onModifierFinished():
recycle((MySprite) pItem);
I'd still be curious on anyone's thoughts on the best approach, but I think I may have just missed the obvious here.
I'm going to go ahead and answer my own question to help those in this situation. The short answer is that it's proper to use the IEntity parameter rather than an object outside it. The second issue I ran into when doing this is that I wanted to detach the IEntity from the scene in this method but, in AndEngine, it's important that when an IEntity is detached from the scene it must happen in the UpdateThread--otherwise you have a chance of errors as the scene is drawing while something is being removed from it. The end result looks like this:
#Override
public void onModifierFinished(IModifier<IEntity> pModifier, final IEntity pItem) {
pool.getContext().runOnUpdateThread(new Runnable() {
#Override
public void run() {
pItem.detachSelf();
}
});
}
One other small but important point is the "final" modifier on the Ientity parameter--necessary so that it can be called within the run() thread.

Categories

Resources