How to upload an image to storage firebase from an url - android

When I get the ImageURI from the edamam API and try to upload it it gives some errors, which I am not getting when I transform the BitMap I get when taking a picture and transform it into URI, I have tried to transform the ImageURI into Bitmap to pass it to the same function but that doesnt work. This below is the function that does work
fun bitmapToUri(imageBitmap: Bitmap, cacheDir: File): Uri {
val baos = ByteArrayOutputStream()
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
data2 = baos.toByteArray()
val file = File(cacheDir, imageBitmap.toString())
// When calling it with imageBitmap.toString() each item has its image (before the same one repeated)
file.delete()
// Just in case there is another File
file.createNewFile()
val fileOS = FileOutputStream(file)
fileOS.write(data2)
fileOS.flush()
fileOS.close()
baos.close()
return file.toUri()
}
I am getting these errors
E/UploadTask: could not locate file for uploading:
https://www.edamam.com/food-img/28a/28ae0e32feff919253b2cd17c47d2f23.jpg
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 0
E/StorageException: No content provider: https://www.edamam.com/food-img/28a/28ae0e32feff919253b2cd17c47d2f23.jpg
java.io.FileNotFoundException: No content provider: https://www.edamam.com/food-img/28a/28ae0e32feff919253b2cd17c47d2f23.jpg
This is the function I have to upload to Storage
private fun uploadImage() {
val name = binding.inputName?.editText?.text.toString()
val provider = binding.inputProvider?.editText?.text.toString()
val address = binding.inputStreet?.editText?.text.toString()
val fileName = "$name $provider $address"
Log.d("INFO IMAGE URI UPLOAD->>", imageUri.toString())
storage = FirebaseStorage.getInstance().getReference("images/$fileName")
storage.putFile(imageUri).addOnSuccessListener {
binding.imageButton.setImageURI(null)
}.addOnFailureListener {
Toast.makeText(this#NewItem, "Image Not Uploaded", Toast.LENGTH_SHORT).show()
}
}
And this is the value I'm passing to imageUri
imageUri = apiCallBody.listHints.first().food.image.toUri()
Which is this value
https://www.edamam.com/food-img/862/862434152a3191f30c889f10eb2989b0.jpg

The Firebase Storage SDK doesn't allow you to directly upload the contents of random http URLs like the one you're showing here. The putFile method requires a Uri from a ContentProvider that's serviced by an Android app on the device. That's not what you're doing here at all.
If you want to upload an image that exists outside your app, you will have to download it first locally, then upload the data that you downloaded using putBytes, putStream or putFile.

My Method of setting a selected Image to a image view to then be Uploaded is
private val ImageLauncher = registerForActivityResult(ActivityResultContracts.GetContent()){ uri: Uri? ->
uri?.let { binding.GroupImageAdd.setImageURI(uri)
ImageUri = uri
}
}
The Uri is a Local val
set when the images is selected from file
and then
fun UploadImage(UUid: String, uri: Uri, ImageType: String) {
val storageRef = FirebaseStorage.getInstance().reference
Log.d("URI", uri.toString())
val task = storageRef.child("**Image Directory").putFile(uri)
task.addOnSuccessListener {
Log.d("UploadImage", "Task Is Successful")
}.addOnFailureListener {
Log.d("UploadImageFail", "Image Upload Failed ${it.printStackTrace()}")
}
}
Unsure if this helps

Related

How to convert bitmap to file

I must upload image file by use retrofit
this is Api
#POST("/image")
suspend fun uploadImage(
#Body request: UploadImageRequest,
): Response<UploadImageResponse>
UploadImageRequest
data class UploadImageRequest(
#SerializedName("image") val image: String,
)
I implement get image in device storage
this is code that get image
private val imageResult = registerForActivityResult(
StartActivityForResult(),
) { result ->
if (result.resultCode == RESULT_OK) {
val imageUri = result.data?.data
imageUri?.let {
if (Build.VERSION.SDK_INT < 28) {
bitmap =
MediaStore.Images.Media.getBitmap(this.contentResolver, imageUri)
} else {
val source = ImageDecoder.createSource(this.contentResolver, imageUri)
bitmap = ImageDecoder.decodeBitmap(source)
}
}
binding.imageActivityChangeUserInformationUserProfile.setImageBitmap(bitmap)
}
}
I don't know how I can upload that image
I tried that image to string by use base64 encode
but encoding string is too long
I tried create temp image file in device storage.
But, changed policy, scoped storage?
I couldn't make a new file
my app sdk is 33
If you have a file and you want to upload that file then do not first make a bitmap out if it.
Certainly not if you then ask to save that bitmap to file as then you can start over again.
And pdf's and doc's let them convert to bitmap pretty bad.
So just upload the file.
Just the bytes of the file.

How to get callback in andorid after uploading of file is complete using Azure blob storage?

I'm uploading user's profile pic to azure server using Azure blob storage.
This is my code
fun uploadImage(path: String, fileInputStream: FileInputStream) =
viewModelScope.launch(Dispatchers.IO) {
try {
val storageAccount = CloudStorageAccount.parse(connectionString)
val bobClient = storageAccount.createCloudBlobClient()
val container = bobClient.getContainerReference(storageContainer)
val blob = container.getBlockBlobReference("$storageContainer.jpg")
val file = File(path)
blob.upload(fileInputStream, file.length() )
} catch (e: Exception) {
e.printStackTrace()
}
}
The code is working fine and the image is uploading, when I checked using the URL, but how can I get a callback on success or error of uploading, so that I can perform action on the basis of that.
How can I know when upload finishes or if any error occurred?

Error occured when using OnGifSelected to send a gif message

This is for my messaging app, whenever I try to send a gif from this GIPHY UI SDK, I get this error: An unknown error occurred, please check the HTTP result code and inner exception for server response.
override fun onGifSelected(media: Media, searchTerm: String?, selectedContentType: GPHContentType) {
val image = media.images.fixedWidth
val gif_url = image!!.gifUrl
val gifUri = Uri.parse(gif_url)
val reference2 = FirebaseDatabase.getInstance().getReference("Friends")
reference2.child(firebaseUser!!.uid)
.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.hasChild(visitorsUid!!)) {
//progressDialog
val pd = ProgressDialog(this#ChatActivity)
pd.setTitle("Please wait...")
pd.setMessage("Sending Gif...")
pd.setCanceledOnTouchOutside(false)
pd.show()
val databaseReference = FirebaseDatabase.getInstance().reference
//file name and path in firebase storage
val filenamePath = "Gif Images/" + firebaseUser!!.uid + System.currentTimeMillis()
val storageReference = FirebaseStorage.getInstance().getReference(filenamePath)
//upload image
storageReference.putFile(gifUri!!)
.addOnSuccessListener { taskSnapshot ->
//image uploaded, get url
val p_uriTask = taskSnapshot.storage.downloadUrl
while (!p_uriTask.isSuccessful);
val p_downloadUri = p_uriTask.result
if (p_uriTask.isSuccessful) {
//image url recieved, save in db
//timestamp
val timestamp = "" + System.currentTimeMillis()
//setup message data
val hashMap = HashMap<String, Any>()
hashMap["sender"] = firebaseUser!!.uid
I think the problem is with this line
val gifUri = Uri.parse(gif_url)
I tried to upload it to my firebase storage
storageReference.putFile(gifUri!!)
Here's what my logcat shows
E/StorageException: No content provider: https://media3.giphy.com/media/iJbxNEqePoPp7l8I0g/200w.gif?cid=e8dbb930ge42y7jitdl6z424143u7ah6bti5nmz7v16mdi53&rid=200w.gif
java.io.FileNotFoundException: No content provider: https://media3.giphy.com/media/iJbxNEqePoPp7l8I0g/200w.gif?cid=e8dbb930ge42y7jitdl6z424143u7ah6bti5nmz7v16mdi53&rid=200w.gif
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1969)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1798)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1475)
There is no way to upload a file to Firebase Storage directly from a URL. You will first have to download the data from the URL, and then upload that local data to Firebase as either a String, a local File object, or a Stream.
Also see:
Upload image from URL to Firebase Storage, which has some valid answers wondering why you'd want to copy the file over to Firebase Storage if Giphy already hosts it.

Kotlin: How to convert an image Uri to Bitmap to Base64

I've found lots of answers related tothis in Java, supposedely a Kotlin solution would be very much like Java, but as in many other things, the devil is on the details, and there are some.
I have several Uris stores in the SQLite database I'm using, now I want to send this images to an API that will catch them along with other data. I'll send the info via POST.
So now, I want to load the Uri, as I do when I use an ImageView.setImageURI() that will take the Uri, convert to Bitmap and place it in the ImageView container.
How do I convert from that Uri to a Bitmap object, and then encode it to Base64 to send it to the API, using Kotlin code?
EDIT
I'm trying with Anupam's imageFileToBase64() which seems to be exactly what I want, now I'm having a problem, I got a FileNotFoundException. This is what I'm doing.
I recover the Uri string from the database, it is a string that reads: content://media/external/images/media/109, so I convert it to an Uri
val uri = Uri.parse(uri_string)
Then I get the real path, and convert it to File
val file = File(uri.path)
Finally I call the function
val base64 = imageFileToBase64(file)
I have tried both with uri.path and uri.toString() and got the same results.
uri.path = /external/images/media/109
uri.toString() = content:/media/external/images/media/109
So I got no idea on what to pass to the function.
These are Kotlin methods for the following -
1. Get the bitmap from assets
2. Save bitmap to a file
3. Get Base64 from bitmap
4. Encode File/Image to Base64
5. Decode Base64 to File/Image
// Get the bitmap from assets and display into image view
val bitmap = assetsToBitmap("tulip.jpg")
// If bitmap is not null
bitmap?.let {
image_view_bitmap.setImageBitmap(bitmap)
}
val imagePath = "C:\\base64\\image.png"
// Encode File/Image to Base64
val base64ImageString = encoder(imagePath)
println("Base64ImageString = $base64ImageString")
// Decoder Base4 to File/Image
decoder(base64ImageString, "C:\\base64\\decoderImage.png")
// Click listener for button widget
button.setOnClickListener{
if(bitmap!=null){
// Save the bitmap to a file and display it into image view
val uri = bitmapToFile(bitmap)
image_view_file.setImageURI(uri)
// Show a toast message
toast("Bitmap saved in a file.")
}else{
toast("bitmap not found.")
}
}
}
// Method to get a bitmap from assets
private fun assetsToBitmap(fileName:String):Bitmap?{
return try{
val stream = assets.open(fileName)
BitmapFactory.decodeStream(stream)
}catch (e:IOException){
e.printStackTrace()
null
}
}
// Method to save an bitmap to a file
private fun bitmapToFile(bitmap:Bitmap): Uri {
// Get the context wrapper
val wrapper = ContextWrapper(applicationContext)
// Initialize a new file instance to save bitmap object
var file = wrapper.getDir("Images",Context.MODE_PRIVATE)
file = File(file,"${UUID.randomUUID()}.jpg")
try{
// Compress the bitmap and save in jpg format
val stream:OutputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream)
stream.flush()
stream.close()
}catch (e:IOException){
e.printStackTrace()
}
// Return the saved bitmap uri
return Uri.parse(file.absolutePath)
}
// Method to get Base64 from bitmap
private fun imageFileToBase64(imageFile: File): String {
return FileInputStream(imageFile).use { inputStream ->
ByteArrayOutputStream().use { outputStream ->
Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
inputStream.copyTo(base64FilterStream)
base64FilterStream.flush()
outputStream.toString()
}
}
}
}
// Encode File/Image to Base64
private fun encoder(filePath: String): String{
val bytes = File(filePath).readBytes()
val base64 = Base64.getEncoder().encodeToString(bytes)
return base64
}
// Decode Base64 to File/Image
private fun decoder(base64Str: String, pathFile: String): Unit{
val imageByteArray = Base64.getDecoder().decode(base64Str)
File(pathFile).writeBytes(imageByteArray)
}

deleting an image file from the file system and then adding a new image file with the same name returns an old image when added using Uri in android

I'm trying to create an application where i am required to add or delete an image simultaneously from image view and external storage. While doing the same, when I try adding the new image into the imageview using Uri, the old image keeps getting added again.
Here is my code
if (resultCode == Activity.RESULT_OK && requestCode == IMAGE_PICK_CODE_GALLERY) {
var selectedImage = data?.data
try {
val bitmap = MediaStore.Images.Media.getBitmap(context?.contentResolver,selectedImage)
if(bitmap!=null) {
val imageURI: String = getImageUri(context!!, bitmap)
}
private fun getImageUri(context: Context, inImage: Bitmap): String {
var fOut: OutputStream?
var path: String? = null
var fileName: String? = abc
var file: File? = null
file = File(
Environment.getExternalStorageDirectory().toString() + File.separator + "myDirectory",
"$fileName"
)
if (file.exists())
{
file.getCanonicalFile().delete()
if (file.exists())
{
context?.deleteFile(file.getName())
}
file.delete()
}
file.createNewFile() //If file already exists will do nothing
fOut = FileOutputStream(file)
inImage.compress(Bitmap.CompressFormat.JPEG, 40, fOut)
Glide.with(this).load(file).into(imageView!!)
fOut.flush()
fOut.close()
// path = MediaStore.Images.Media.insertImage(context.contentResolver,file.absolutePath,file.getName(),null);
} catch (ex: Exception) {
ex.printStackTrace()
}
return file.toString()
}
Glide caches your images, so probably you are loading a cached version of the old image.
As suggested in Glide's docs you should add a signature to handle cache invalidation:
Glide.with(yourFragment)
.load(yourFileDataModel)
.signature(new ObjectKey(yourVersionMetadata))
.into(yourImageView);

Categories

Resources