I want to pick the images with the extension "bmp" through the intent. I have tried passsing the "image/bmp" but it didn't worked. So what's the working way to get the "bmp" extension images through the intent.
Convert it into a string. First you need to convert the file to a .jpg or .png file, (you will have to do this manually outside of code), then convert to bitmap:
Bitmap bmp = BitmapFactory.decodeFile( PathToFileString );
or
Bitmap bmp = BitmapFactory.decodeFileDescriptor( fileDescriptorObject );
then
fun encode(imageUri: Uri): String {
val input = activity.getContentResolver().openInputStream(imageUri)
val image = BitmapFactory.decodeStream(input , null, null)
// Encode image to base64 string
val baos = ByteArrayOutputStream()
image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
var imageBytes = baos.toByteArray()
val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
return imageString
}
fun decode(imageString: String) {
// Decode base64 string to image
val imageBytes = Base64.decode(imageString, Base64.DEFAULT)
val decodedImage = BitmapFactory.decodeByteArray(imageBytes, 0,
imageBytes.size)
imageview.setImageBitmap(decodedImage)
}
Once you have your string, then put it into an intent:
val intent = Intent(this, YourClass::class.java)
intent.putExtra("image", yourString);
startActivity(intent)
Related
I get the following error when trying to iterate over the uploadTasks inside an addOnSuccessListener method.
java.lang.ClassCastException: com.google.firebase.storage.UploadTask$TaskSnapshot cannot be cast to com.google.firebase.storage.UploadTask
So how can i get the Download String of each Img inside addOnSuccessListener?
val baos = ByteArrayOutputStream()
val tasks = mutableListOf<UploadTask>()
listImg.forEach {
if(bitmap!!.byteCount != it.byteCount) {
val bitmap = it
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
var uploadTask = spaceRef.putBytes(data)
tasks.add(uploadTask)
}
}
Tasks.whenAllSuccess<UploadTask>(tasks).addOnSuccessListener { uploadTasks ->
//uploadTasks has size of 2
val urls = mutableListOf<Uri>()
lifecycleScope.launch
{
//Error throws here
uploadTasks.forEach{
urls.add(it.await().storage.downloadUrl.await())
}
}
}
The type of whenAllSuccess is <TResult>, so you should use the result type of UploadTask (UploadTask.TaskSnapshot) instead:
Tasks.whenAllSuccess<UploadTask.TaskSnapshot>(tasks).addOnSuccessListener { uploadTasks ->
And then you can drop the the first await() on that last line:
urls.add(it.storage.downloadUrl.await())
Bonus: Don't block the main thread
Note that Tasks.whenAllSuccess() will block the main thread until all uploads succeed, meaning your UI might freeze while uploading files.
To avoid that, consider uploading your files with Coroutines:
val baos = ByteArrayOutputStream()
val urls = mutableListOf<Uri>()
lifecycleScope.launch {
listImg.forEach {
if(bitmap!!.byteCount != it.byteCount) {
val bitmap = it
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
// Upload the image first
val taskSnapshot = spaceRef.putBytes(data).await()
// Get the download Url
val downloadUri = taskSnapshot.storage.downloadUrl.await()
// Add it to the list of Uris
urls.add(downloadUri)
}
}
}
I have an app that has image upload feature and after uploading the image on onActivityResult() I receive the Uri of the image and turn it into bitmap with the following function :
private fun uriToBitmap(selectedFileUri: Uri): Bitmap? {
return try {
val parcelFileDescriptor: ParcelFileDescriptor =
requireContext().contentResolver.openFileDescriptor(selectedFileUri, "r")!!
val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor
val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor.close()
image
} catch (e: IOException) {
e.printStackTrace()
null
}
}
but for some reason my image rotates 90 degrees if it was a portrait image
I have tried using the ExifInterface thing for fixing it and rotating it back with this function :
fun determineImageRotation(imageFile: File, bitmap: Bitmap): Bitmap {
val exif = ExifInterface(imageFile.absolutePath)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)
val matrix = Matrix()
when (orientation) {
6 -> matrix.postRotate(90f)
3 -> matrix.postRotate(180f)
8 -> matrix.postRotate(270f)
}
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
but I receive this error :
ExifInterface got an unsupported image format file(ExifInterface supports JPEG and some RAW image formats only) or a corrupted JPEG file to ExifInterface.
java.io.EOFException
this is how I create a file path for the image :
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String =
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val storageDir = requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"PNG_${timeStamp}_", /* prefix */
".png", /* suffix */
storageDir /* directory */
)
}
here is an example of a file path that I have for an image :
/storage/emulated/0/Android/data/avedot.app/files/Pictures/PNG_20210622_094219_232594250744276112.png
I assume there is something with the path that is related to the dot in avedot.app whice breaks the ExifInterface function but how can I work around this ?
Thanks in advance !
i want request to Flask server.
so, i converted a img to JSON data in Kotlin(Android Studio)
Although JSON data is well sent and received from the server, the size of the transmitted data is five times larger than the original data.
what should i do to get exact data from server??
Simple Server Code(python)...
print(len(request.json['file']))
img_data = base64.b64decode(request.json['file'])
filename = 'received_now_starry_night.png'
with open(filename, 'wb') as f:
f.write(img_data)
dic = {
"msg":"hello"
}
return jsonify(dic)
Android Studio, kotlin Code...
val bitmap:Bitmap = BitmapFactory.decodeResource(resources, R.drawable.starry_night)
val bos:ByteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos)
val image:ByteArray = bos.toByteArray()
val base64Encoded = java.util.Base64.getEncoder().encodeToString(image)
val rootObject = JSONObject()
rootObject.put("file", base64Encoded)
To convert an image to Base64 String :
You can also create a resized Bitmap and compress it to decrease the size
private fun CreateImageStringFromBitmap(): String {
val bitmap:Bitmap = BitmapFactory.decodeResource(resources, R.drawable.starry_night)
val resized = Bitmap.createScaledBitmap(
bitmap:Bitmap, (desired width).toInt(),
(desired height).toInt(), true
)
val stream = ByteArrayOutputStream()
resized.compress(Bitmap.CompressFormat.PNG, 75, stream)
val byteArray: ByteArray = stream.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
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)
}
How to convert imageview to bytearray kotlin android
In java
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
return image
Here it is use java to kotlin converter.
val bitmap = (image.getDrawable() as BitmapDrawable).getBitmap()
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream)
val image = stream.toByteArray()
This may help you,
private fun imageToBitmap(image: ImageView): ByteArray {
val bitmap = (image.drawable as BitmapDrawable).bitmap
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream)
return stream.toByteArray()
}