How to show image in fragment ImageView from firebase storage - android

I wanted to know is there a way i can show my image view image in fragment.
The image i am getting is from Firebase storage and passing the bitmap value through a view Model function and including the value in the fragment.
I wanted to know is there a better way to do this?
Also when there is no image, the image still shows when i pair it up with androidswipetorefresh listener
Main Activity Code
val imageName = auth.currentUser?.uid
val storageRef = FirebaseStorage.getInstance().reference.child("profileImages/$imageName.jpg")
val localFile = File.createTempFile("tempImage","jpg")
storageRef.getFile(localFile).addOnSuccessListener {
val bitmap = BitmapFactory.decodeFile(localFile.absolutePath)
fragmentViewModel.setImage(bitmap)
}.addOnFailureListener {
Toast.makeText(this,"Failed",Toast.LENGTH_SHORT).show()
}
Fragment Code
profileImg = view.findViewById(R.id.profileImage)
val bitmap = viewModel.imageData.value
profileImg.setImageBitmap(bitmap)
View Model Code
val imageData = MutableLiveData<Bitmap>() fun setImage (newData: Bitmap) {
imageData.value = newData
}

When getting images from a specific URL, it's more likely to be used a third-party library that can do the job for you. So, I definitely recommend you to use an image loading and caching library. For Android we have Glide:
Glide is a fast and efficient open-source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy-to-use interface.

Related

getting image Uri in android

i am wanting to grab the image uri, upload it to firebase in order for it to be available there and other users r able to see this image when connecting to the firebase database. only issue is when an image is selected, firstImage is set as content://com.android.providers.media.documents/document/image%3A525 which doesn't have the extension, whether it's .png, etc.
the logic below is done in a composable function which is y something like gallery intent isn't used.
any insights?
var firstImage by remember { mutableStateOf<Uri?>(null) }
val firstLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()) { uri ->
uri?.let { firstImage = it }
}

Use string url or URI for image properties of object

I want to store object to data room. when i create an object like account with name, phone number, email and images taken from gallery. Should I use string or uri for images so that objects can be easily passed between activities?
You should copy images to the app's local storage and store that copied image path in the database.
For copying the image to the app's local storage after getting the selected image uri
val dir = requireActivity().getDir(FOLDER_TO_SAVE, Context.MODE_PRIVATE).path
val copiedImage = File(dir, UUID.randomUUID().toString() + ".jpg")
val copiedImageUri = Uri.fromFile(file)
receivedImageUri.path?.let {
File(it).copyTo(copiedImage)
}
Get path of the copied image, using its uri
copiedImageUri.path.?.let{
val copiedImagePath = "file://$it"
//now save this path to your database
}
Use this saved image path as string to exchange between activities.
I think better to store this image as object BLOB
otherwise if you removed this image from gallery it will not be able to get this, because Room, will stored only link not an object. I hope it will be useful
#Entity(tableName = "user")
public class User{
#ColumnInfo(typeAffinity = ColumnInfo.BLOB)
private byte[] image;
}

How to get Video thumbnail from URL

I am trying to generate a thumbnail of the video. But I cannot use Glide as it colliding with other gallery libraries.
I have tried Picasso that is not giving me thumbnail from the URL. ThumbnailUtils.createVideoThumbnail is working in my code but it is too slow.
Can someone suggest any effective tool or technique, to get the thumbnail from the URL in java??
You can use the MediaMetadataRetriever class. For example
private fun getThumbNail(uri: Uri): Bitmap {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(context, uri)
return retriever.frameAtTime //or frameAtPosition(..)/frameAtIndex(..)
}

How to correctly download firebase storage images into recycelrView

I have recyclerview and in every row I have an image that I load with firebase storage. It seems like the image loading is affecting the scrolling performance of the recyclerView.
I am using glide to load the images that I got from firebase inside onBindViewHolder by calling imageLoadGlide method like this:
//Download image from firebase Storage and set gameImage("ImageView") image.
private void imageLoadGlide(DocumentSnapshot documentSnapshot, final QuestionsHolder questionsHolder) {
//for firebase storage
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
storageRef.child(documentSnapshot
.get("image").toString())
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//this part is loading image from url library
Glide
.with(context.getApplicationContext()) // pass Context
.load(uri)// pass the image url
.centerCrop() // optional scaletype
.crossFade() //optional - to enable image crossfading
.transform(new CircleTransform(context))//transfoms the imageView onto circle with the custon class CircleTransform
.into(questionsHolder.gameImage); // the ImageView to which the image is to be loaded
//stop the loading bar from spinning
questionsHolder.loadProgress.setVisibility(View.GONE);
}
});
}
The download works fine but it makes the scrolling super slow.
I have no idea why this is happening because I compress the images before uploading them so I don't think that this is a problem of image weight.
The image compress is made like this :
Bitmap bitmap = ((BitmapDrawable) questionImage.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);
Any ideas on why this is happening and how can I avoid this?
Here is onBindViewHolder for #Vadim Eksler request:
#Override
public void onBindViewHolder(#NonNull final QuestionsHolder holder, final int position) {
holder.gameImage.setImageBitmap(null);
setInfoForViews(holder, result.get(position));
imageLoadGlide(result.get(position), holder);
setOnClicksListners(holder, position);
setRankTextView(position, holder);
if (position == result.size() - 1 && !endOfDocs && next != null) {
loadMoreDocs(position);
}
}
This answer is based on all the comments together.
So as mentioned in the comments what I did wrong is that every time that onBindViewHolder was called I have pulled the image from firebase again and again - this causes poorly recyclerView performance.
What I did to fix it:
I have used flyweight design pattern to load the image only for the first time from firebase and after that simply recycle this image for the next time onBindViewHolder will get called.
First I created a map as a global variable:
private Map<String, Bitmap> flyweight = new HashMap<>();
after that when the image is loaded from the first time I will save it for later when onBindViewHolder will get called again:
Inside onBindViewHolder :
if (flyweight.get(result.get(position).get("image").toString()) == null) {
imageLoadGlide(result.get(position), holder); // load the image
} else {
//recycle the image that i already have
holder.gameImage.setImageBitmap(flyweight.get(result.get(position).get("image").toString()));
}
And the last thing is to add my image to the map that I created after the image is successfully pulled :
flyweight.put(documentSnapshot.get("image").toString(), resource);

Read and load images from SDcard asynchronously - fail

I'd like to load image which is on SDCARD in folder to imageView of my cell in listView. I've tried different solutions but each of them fails. When I load images normally as it is in every base tutorial everything works. I've observed that, my application slows down when it has to load many images. Images are taken from photo camera of device. I'd like to load each of them asynchronously to avoid UI slow reaction. I've tried to use Thread, Asynctask but each of them throws error: "Only the oryginal thread that created a view hierarchy can touch its views". How to load images to avoid speed problems? SDImageLoader is a class which is possible to get from GITHUB. What I've tried is a standard code but is slows:
In a getView method in ListAdapter:
File imageFile = new File(Options.PATH_TO_FOLDER_PHOTOS_OF_APP + "test.png");
String imageFileString = Options.PATH_TO_FOLDER_PHOTOS_OF_APP + "test.png";
// "test.png" is a test file. Each cell will have different name of file to load.
if(imageFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
image.setImageBitmap(myBitmap);
// final SDImageLoader loader = new SDImageLoader(context);
// new SDImageLoader().load(imageFileString, image);
//UrlImageViewHelper.setUrlDrawable(image, url);
}
else
{
final SDImageLoader loader = new SDImageLoader();
Resources resources = context.getResources();
int resurceId;
resurceId = resources.getIdentifier("bad", "drawable",context.getPackageName());
loader.load(imageFileString, image);
image.setImageResource(resurceId);
}
Have you tried to refresh your project after adding an external library to your project? It doesn't matter with the fragment. You send exact context to the List Adapter - which should be fragment.this.getActivity().

Categories

Resources