Android storing SVG in assets then decoding to bitmap - android

I currently have a huge amount of PNGs in my assets folder. When i launch my app i retrieve the file path of each one and use it to convert to a bitmap when that specific png is needed like so
fun getImageBitmapFromAsset(assetManager: AssetManager, imagePath: String?): ImageBitmap {
val inputStream: InputStream
var bitmap: Bitmap
try {
inputStream = assetManager.open(imagePath!!)
bitmap = BitmapFactory.decodeStream(inputStream)
} catch (e: IOException) {
return emptyImageBitmap
}
return bitmap.asImageBitmap()
}
My question is can this be done with SVGs and how?

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.

Bitmap is lost the quality of image when getting from the storage of android

I am facing issue with Bitmap image quality when getting a image file from internal storage and show on imageView. How to show image file with original quality using bitmap.
Here is my code
fun renderPdf(renderer: PdfRenderer, pagesBitmap: MutableList<Bitmap>, dir: File) {
try {
for (i in 0 until PAGE_COUNT) {
val document: PDDocument = PDDocument.load(dir)
val pdfRenderer = PDFRenderer(document)
val bim = pdfRenderer.renderImage(i, 3.5f, Bitmap.Config.ARGB_8888!!)
pagesBitmap.add(bim!!)
document.close()
// Save the render result to an image
val path: String =
Environment.getExternalStorageDirectory().toString() + "/.AOF/aof_$i.jpg"
val renderFile = File(path)
val fileOut = FileOutputStream(renderFile)
pagesBitmap[i].compress(Bitmap.CompressFormat.JPEG, 100, fileOut)
fileOut.close()
}
ivForm.pagesBitmap = pagesBitmapFiles
ivForm.displayPDFDocument()
renderer.close()
} catch (e: IOException) {
Log.e("PdfBox-Android-Sample", "Exception thrown while rendering file", e)
} finally {
callDocumentType()
}
}

Uri to bitmap conversion rotates the image

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 !

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

Display pdf in android

I have written a c# web service that returns a pdf in a stream of bytes as response. Once I make a call to the web-service from my android app, I will store the response in an array byte till here I will be able to do it. But after that I need to convert that byte array into pdf, I should be able to display that. I have a menu page in which once the button is pressed the call is made to the web service with file name and on click of button I should be able to open pdf. Is this possible? Or there is some other, better solution? I checked on the net for better understanding, but I was unable to find one that could help me understand better.
Thanks for the suggestion, but I don't have the pdf in hand, I just have the array bytes, which I got from the web service. So I now need to regenerate the pdf from this array of bytes and display it, but I am not getting how to do it.
Try following these steps
Convert byte array to InputStream
val inputStream = ByteArrayInputStream(byteArray)
Save InputStream as PDF file:
suspend fun saveInputStreamAsPdfFile(inputStream: InputStream, applicationContext: Context): File? {
var outputFile: File? = null
withContext(Dispatchers.IO) {
try {
val directory = ContextCompat.getExternalFilesDirs(applicationContext, "documents").first()
val outputDir = File(directory, "outputPath")
outputFile = File(outputDir, UUID.randomUUID().toString() + ".pdf")
if (!outputDir.exists()) {
outputDir.mkdirs()
}
val outputStream = FileOutputStream(outputFile, false)
inputStream.use { fileOut -> fileOut.copyTo(outputStream) }
outputStream.close()
} catch (e: Exception) {
// Something went wrong
}
}
return outputFile
}
Show PDF with PdfRenderer
var totalPdfPages: Int
fun showPdf(pdfFile: File) {
val input = ParcelFileDescriptor.open(pdfFile, MODE_READ_ONLY)
val renderer = PdfRenderer(input)
val wrapper = PdfRendererWrapper(renderer)
totalPdfPages = wrapper.getTotalPages()
showPdfPage(0)
}
fun showPdfPage(currentPageIndex: Int) {
val pageBitmap = wrapper.getBitmap(currentPageIndex)
imageView.setImageBitmap(pageBitmap) // Show current page
}

Categories

Resources