Rewind button with picasso - java

I am making an application that generates a random image by a url when touching the button and presents it in the imageview and I use picasso and to change the image you have to clear the cache and I would like someone to tell me how I could go back to the previous image, like a back button
Any help is appreciated from the heart
My code to generate a new image:
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String quest1 = "https://proxxcraft.com/";
Picasso.get().load(quest1).memoryPolicy(MemoryPolicy.NO_CACHE).into(memeRandomView);
Picasso.get().isLoggingEnabled();
}
});

you should save the image as a bitmap, save it in an array or some other data structure. I know how to do it with glide but you should check for how to set callbacks to know when the image is loaded.
private void loadImage() {
Picasso.with(this)
.load("https://proxxcraft.com/")
.into(mContentTarget);
}
private Target mContentTarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
//save the bitmap in an array so you can use it later.
Imageview.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};

Related

Recycler view mixing up the contents of its items

I'm using a recycler view to load a list of posts made by and organization. I've used firestore as the backend.
For loading the image I'm first getting the download Url from storage reference and then using Glide to load image in to the image view.
The issue i'm facing is that since a call to the storage reference is an asynchronous one, by the time it gets the download uri from the server the position of the adapter in OnBindviewHolder is already changed Therefore image gets mixed up.
I've provided the OnBindViewHolder code and the method where i get the download url
#Override
public void onBindViewHolder(#NonNull final studentFavouriteUniversityPosts.MyViewHolder holder, int position) {
if(postsList.get(holder.getAdapterPosition()).getImageUrl()!=null &&
!postsList.get(holder.getAdapterPosition()).getImageUrl().isEmpty()){
holder.setPostImage(holder.getAdapterPosition());
}
}
public void setPostImage(int position) {
postImage.setVisibility(View.VISIBLE);
placeholder.placeholder(R.color.white);
//Getting the download uri from the Fire store storage and displaying it using glide.
storageReference.child(postsList.get(position).getImageUrl())
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Log.d("URI",uri.toString());
Glide.with(context).applyDefaultRequestOptions(placeholder).load(uri).into(postImage);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("ERROR","err loading image file");
}
});
}
Can anyone of you help me out on this?
EDIT
I changed the structure a bit. So instead of running the storage reference task in adapter, i'm storing the dowload url in the object. Thus the setPostImage method only has the Glide part.
So the method looks like this
public void setPostImage(String downloadURL) {
postImage.setVisibility(View.VISIBLE);
Glide.with(context).applyDefaultRequestOptions(placeholder).load(downloadURL).into(postImage);
}
Still i'm getting this issue. I dont know how to resolve it
First get the list of urls from firestore from the activity or fragment where you are
setting the adapter
1. public void getImages() { storageReference.child("the child name")
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Log.d("URI",uri.toString());
adapter.imagesRetrieved();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("ERROR","err loading image file");
}
});
}
2. Then inside on success listener pass the group of values to the adapter method from the success listener and define the method inside the adapter
public void imagesRetreived() {
notifyDataChanged(images);
}
private void notifyDataChanged(Images images) {
this.images = images;
notifydatasetchanged(); //this one is recycler view inbuilt method
}

Picasso Library loads my Images too slow?

I'm using Picasso to display many small ImageViews in a RecyclerView.
The ImageViews change their Image for 500 milliseconds when I click on them and change it back when the handler with 500 milliseconds end.
This is the code:
Picasso.get().load(imageResources[position]).into(holder1.itemImageView);
holder1.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final Context context = v.getContext();
Picasso.get().load(pressedResource[position]).into(holder1.itemImageView);
new Handler().postDelayed(new Runnable() {
public void run() {
Picasso.get().load(imageResources[position]).into(holder1.itemImageView);
}
}, 500);
new Thread(new Runnable() {
#Override
public void run() {
EventHandlerClass.startMediaPlayer(v, soundID);
}
}).start();
}
});
I use Picasso to prevent my app from getting OutOfMemory crashes.
The Image Dissapears for like 10 milliseconds, then changes to the other image, after the 500 milliseconds it dissapears again and then it changes back to the default image.
It only dissapears for the first time I click on one of the Images, after that it works without dissapearance.
I think this happens because Picasso is loading the image too slow.
Is there a way to first load the image and display it when I click on the button?
Here is a GIF which shows how it looks like: https://media.giphy.com/media/STlGbpXvT8B9iBvnQS/giphy.gif
In this case it only dissapeared once but sometime it dissapeares twice with one click.
The Images are all 200x200 and around 8kb. The format is .WEBP
How can I prevent this?
The idea is to wait for the Callback and then set the image into the image view. This is achieved by using a CallbackListener.
Picasso.get().load(imageResources[position]).into(holder1.itemImageView);
holder1.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final Context context = v.getContext();
Picasso.get().load(pressedResource[position]).into(holder1.itemImageViewnew com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
new Handler().postDelayed(new Runnable() {
public void run() {
Picasso.get().load(imageResources[position]).into(holder1.itemImageView);
}
}, 500);
new Thread(new Runnable() {
#Override
public void run() {
EventHandlerClass.startMediaPlayer(v, soundID);
}
}).start();
}
#Override
public void onError() {
}
}));
}
});

App crashes when using bitmap and mat with OpenCV

So I would like to start developing apps using OpenCV. I want try something simple, read an image, convert it to grayscale and then display it.
When I read it and convert it using Mat, the app works fine. When I read it and display it using Bitmaps it works fine as well. When I combine both, read the image using mat, convert it to bitmap it crashes. I don't have a logcat because I can't play the app straight away from the computer so I have to send the .apk every time ...
I downloaded LogcatBrowser and took a screenshot of what I obtained ...
MainAcvitity.Java code:
public class MainActivity extends Activity {
private Bitmap mBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
if (status == LoaderCallbackInterface.SUCCESS ) {
ImageView img = (ImageView)findViewById(R.id.image_view_camera);
Mat m = Highgui.imread("gph.jpg");
//Imgproc.cvtColor(m, m, Imgproc.COLOR_BGR2GRAY);
Bitmap resultBitmap = Bitmap.createBitmap(m.cols(), m.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(m, mBitmap);
img.setImageBitmap(mBitmap);
} else {
super.onManagerConnected(status);
}
}
};
#Override
public void onResume() {;
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5,this, mLoaderCallback);
}
}

why are my images loaded so slow to the listView?

I have a listView with ImageViews.
I try to compress the bitmaps with the following code:
public void getImage(final String urlStr, final ImageView toSet) {
// set the tag immediately, to prevent delayed image downloads from
// setting this image.
toSet.setTag(urlStr);
getImage(urlStr, new ImageRepository.ImageRepositoryListener() {
#Override
public void onImageRetrieved(final Drawable drawable) {
if (drawable == null)
return;
toSet.post(new Runnable() {
#Override
public void run() {
// make sure the tag is still the one we set at the
// beginning of this function
if (toSet.getTag() == urlStr) {
toSet.setImageDrawable(drawable);
drawable.setCallback(null);
}
}
});
}
});
}
public class DownloadImageAsyncTask2 extends
AsyncTask<String, Void, Bitmap> {
private final ImageView imageView;
private String imageUrl;
public DownloadImageAsyncTask2(ImageView imageView) {
this.imageView = imageView;
}
#Override
protected void onPreExecute() {
Log.i("DownloadImageAsyncTask", "Starting image download task...");
}
#Override
protected Bitmap doInBackground(String... params) {
imageUrl = params[0];
try {
imageRepository.getImage(imageUrl, imageView);
return BitmapFactory.decodeStream((InputStream) new URL(
imageUrl).getContent());
} catch (IOException e) {
Log.e("DownloadImageAsyncTask", "Error reading bitmap" + e);
downloadingImageUrls.remove(imageUrl);
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
imageCache.put(imageUrl, bitmap);
downloadingImageUrls.remove(imageUrl);
if (bitmap != null
&& ((String) imageView.getTag()).equals(imageUrl)) {
imageView.setImageBitmap(bitmap);
}
}
}
How can I make the image loading time be faster?
(I have tried to downsize the images on the server side, but I want to think what can I improve in the client side).
I use async download task to download the images and a cache layer to persist them.
Here is the code:
Your image loading is slow because:
After downloading and saving images in the cache , the AsyncTask is used to load but it doesn't give the result immediately.
Firstly, it is controlled by the global Thread's pool with the number maximum of thread in concurrence. Sometimes , it begins after finishing the other AsyncTask .
Secondly, the method "onPostExecute" is executed in Main Thread but after finishing all the other messages of Main Thread.
So:
Use AsyncTask only to download and save images in the cache.
Try to check if the expected image exists in the cache before using AsyncTask. If it exists then you display it directly in Main thread. Make sure that the size of expected image fits well in your image view .
In your case , add the code like this:
public void getImage(final String urlStr, final ImageView toSet) {
//get the expected image associated with this url and the size of this image view in the cache
Bitmap bitmap = getExpectedBitmap(urlStr,expectedSize);
if(bitmap != null) {
//if it exists , set it in the image view and finish.
toSet.setImageBitmap(bitmap);
return;
}
// set the tag immediately, to prevent delayed image downloads from
// setting this image.
toSet.setTag(urlStr);
getImage(urlStr, new ImageRepository.ImageRepositoryListener() {
#Override
public void onImageRetrieved(final Drawable drawable) {
if (drawable == null)
return;
toSet.post(new Runnable() {
#Override
public void run() {
// make sure the tag is still the one we set at the
// beginning of this function
if (toSet.getTag() == urlStr) {
toSet.setImageDrawable(drawable);
drawable.setCallback(null);
}
}
});
}
});
}

How to stop textureview listener and display an image before closing app

I have a simple xml layout as follow with just a TextureView inside a FrameLayout.
And the following main activity:
public class MainActivity extends Activity
implements TextureView.SurfaceTextureListener {
private static final String TAG = "MainActivity";
// Local references to layout components
private TextureView mTxvCameraPreview;
// Camera manager
private CameraManager mCameraManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize layout and components
setContentView(R.layout.activity_main);
mTxvCameraPreview = (TextureView)findViewById(R.id.txv_camera_preview);
// Camera managing
mCameraManager = new CameraManager(this);
mTxvCameraPreview.setSurfaceTextureListener(this);
}
#Override
protected void onResume() {
super.onResume();
if (mTxvCameraPreview.isAvailable())
mCameraManager.startPreview(mTxvCameraPreview.getSurfaceTexture());
}
#Override
protected void onPause() {
super.onPause();
mCameraManager.stopPreview();
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCameraManager.startPreview(surface);
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCameraManager.stopPreview();
return true;
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} // Unused
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {} // Unused
}
For every frame I do some elaboration and it is OK.
What I want is to add a button which stops the camera and display in the TextureView a file load from sdcard.
A pseudo-code of this can be something like this:
public void onButtonClicked(View view) {
// stop the surface listener (it is needed?)
File imgFile = new File(“/sdcard/Images/elaboration_result.jpg”);
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
// show myBitmap on TextureView (if possible)
}
It is possible to do this without modifying the xml layout?
Thanks in advance!
You cannot set the content of a TextureView manually, I'm afraid. Your best bet is to make a new ImageView on top of your TextureView and set its image when you need to.
public void onButtonClicked(View view) {
// if we don't need to keep previewing new frames, stop the preview
mCameraManager.stopPreview();
// now, show our ImageView (which should be in front of the TextureView)
Bitmap myBitmap = BitmapFactory.decodeFile(file_path_here);
myImageView.setImageBitmap(myBitmap);
myImageView.setVisibility(View.VISIBLE);
}
No need to create another Image. Just use
textureView.getBitmap(file.getAbsolutePath);

Categories

Resources