Pass Bitmap image to another activity in Android App - android

Hi I want to pass bitmap from activity 1 to activity 2. It is a large bitmap and I can not use a bundle. Now I save bitmap and pass path and read a path and load bitmap I do this :
val path = saveImage(bitmap)
intent.putExtra("bitmap_path", path)
startActivity(intent)
and in activity2
val f = File(intent.getStringExtra("bitmap_path"))
val bitmap= BitmapFactory.decodeFile(f.absolutePath)
How I can do this better I thing about static object bitmap but I know it is a good practice
edit I do this:
class Helper {
var bitmap: Bitmap? = null
companion object {
val instance = Helper()
}
}

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.

Passing Bitmap through activities

I have two activities and I am trying to pass image by using Serializable way. How to do this? Is it possible to pass image by using Serializable way? Any ideas please.
val resultImage = findViewById<ImageView>(R.id.resultImage)
val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
resultImage.setImageURI(uri)
}
val galleryBtn = findViewById<Button>(R.id.galleryBtn)
val nextBtn = findViewById<Button>(R.id.nextBtn)
galleryBtn.setOnClickListener {
getContent.launch("image/*")
}
nextBtn.setOnClickListener {
val takeImage = resultImage.setImageURI(Uri)
val person = Person ()
Intent(this,SecoendActivity::class.java).also {
it.putExtra("EXTRA_PERSON",person)
startActivity(it)
}
}
In kotlin class file:
data class Person(
val imageUrl: Bitmap
): Serializable
My second activity:
val imageView = findViewById<ImageView>(R.id.imageView)
val person = intent.getSerializableExtra("EXTRA_PERSON")as Person
It is not recommended to use Serializable to pass images between activities, as it can cause memory and performance issues. Instead, you can use the Intent.putExtra method to pass the image's URI to the other activity, and then use the ContentResolver to retrieve the image in the second activity.
// In the first activity
val imageUri = Uri.parse("content://...")
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("image_uri", imageUri)
startActivity(intent)
// In the second activity
val imageUri = intent.getParcelableExtra<Uri>("image_uri")
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri)

Image path failed to store into Object class

In fragment A, I trying to get image object from server and store them into totalListImage. This steps works fine.
var totalListImage: MutableList<Image> = mutableListOf()
fun getWorkRequestImage() {
GlobalScope.launch(Dispatchers.Main) {
val request = WebApi.getImages(activity, obj?.id!!)
request?.images?.let {
for (i in it!!.iterator()) {
totalListImage?.add(i)
}
}
mImageListAdapter.notifyDataSetChanged()
}
}
In same fragment, I allow user to take image and store the captured image into totalListImage.
Here onActivityResult
var path = data?.getExtras()?.getString("bitmap")
if (path != null) {
Log.d(TAG,path)
val images = Image()
images.image?.url = path
totalListImage.add(images)
display()
}
Finally in display method, I want to display all the url. But I get null pointer on the last captured image.
fun display() {
for (i in totalListImage) {
Log.d(TAG, i.image?.url)
}
}
If I remove the captured image, I get this
D/AFragment: https://xxx/image/633/1562424667277.png
D/AFragment: https://xxx/image/637/1562426838223.png
The path of the captured image confirm not null, as I display it I saw this
D/AFragment: /data/user/0/xxxk/cache/images/1562437144046.png
Why I can't save the last image's path into images.image?.url ?
Images
class Images : Serializable {
#PrimaryKey
var id = ""
#Ignore
var image : Image?=null
}
Image
#Parcelize
class Image(
#ColumnInfo(name = "image")
var url: String ? =null
) : Serializable,Parcelable
Referring to this code:
val images = Image()
images.image?.url = path
totalListImage.add(images)
and assuming that you meant val images = Images() (otherwise this snippet won't even compile),
then the issue is that images.image is null.
That's because of the definition of the Images class, where you have var image : Image?=null.
To solve you either:
change the class definition to have a not-null default value, like:
var image : Image? = Image()
or manually initialize it in the snippet above, like:
val images = Images()
images.image = Image()
images.image?.url = path
totalListImage.add(images)

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)
}

Convert Image from RecyclerView to Bitmap

I need to send a specific image from my recyclerview that has been clicked to the new activity that will display the image. The question is how do I convert my image to bitmap or something like that so I can send them using intent?
Here's my code:
RecyclerViewAdapter.kt
class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
fun bindItem(items: Item) {
itemView.name.text = items.name
itemView.desc.text = items.desc
Glide.with(itemView.context).load(items.image).into(itemView.image)
itemView.setOnClickListener {
itemView.context.startActivity(itemView.context.intentFor<DetailsActivity>("image" to bitmap, "name" to items.name, "desc" to items.desc))
}
}
}
SecondActivity
val intent = intent
name = intent.getStringExtra("name")
image = intent.getStringExtra("image")
desc = intent.getStringExtra("desc")
nameTextView.text = name
descTextView.text = desc
Glide.with(this)
.load(image)
.into(imgPhotos)
I have already tried all the code that are provided on this site, but they all didn't work. Thanks!
I am not using Glide but it should be like this.
lateinit imageBitmap : Bitmap
Glide.with(this).asBitmap().load("YOUR_URL").into(object: Target<Bitmap>{
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
imageBitmap = resource
}
})
You can send Bitmap directly because it is Parcelable
intent.putExtra("image",imageBitmap)
To getBitmap
val bitmap = intent.extras.getParcelable<Bitmap>("image")
Convert the image to byteArray and pass it through intent. Extract the data through intent on the other side and convert byteArray into bitmap.

Categories

Resources