Search code examples
androidimagekotlinbitmapandroid-bitmap

PNG image not getting converted from bitmap to png and downloaded to downloads directory


I was working on an app where i remove a portrait image's background (on-device) and download it upon being created. I have created the background removed bitmap of ARGB_8888 type and i was just about to convert it to a png and download it on the user's device, but even after running the download code, it keeps showing no such downloaded file when i check in my device's gallery but using Log statements i am able to see that the download has happened smoothly.

My button that listens to clicking event for downloading is :

downloadbtn.setOnClickListener {
            lifecycleScope.launch(Dispatchers.Default) {
                Log.v("BeforByteStream", "Inside download onclick coroutine")

                requestRuntimePermissions()
                // Permission already granted, proceed with downloading
                downloadToStorage(outputBitmapdnld)


            }
        }

My downloading code from bitmap is :

private fun downloadToStorage(outputBitmapdnld: Bitmap) {
        val bytes = ByteArrayOutputStream().use { stream ->
            outputBitmapdnld.compress(Bitmap.CompressFormat.PNG, 100, stream)
            stream.toByteArray()
        }
        Log.v("AfterByteStream", "Successfully converted to Bytestream!")
        if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            // External storage is available
            //Toast.makeText(this@ImageStaging, "External storage is available!", Toast.LENGTH_SHORT).show()
            // Proceed with saving the image
            Log.v("InsideIf", "External storage is available!")
            val directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
            Log.v("DirectoryAccess", "Directory successfully accessed!")
            val fileName = "bgremove69.png"
            val file = File(directory, fileName)
            if (!file.exists()) {
                file.createNewFile()
            }
            FileOutputStream(file).use { fos ->
                fos.write(bytes)
            }
            Log.v("FileWritten", "File is directly downloaded to folder supposedly...")
        } else {
            // External storage is not available
            Toast.makeText(this@ImageStaging, "External storage is not available", Toast.LENGTH_SHORT).show()
        }
    }

I have successfully asked for image read and write storage permissions from my previous post : Android: Run Time Permissions not working - App Settings Showing No Requested Permissions even when asked for (WRITE_EXTERNAL_STORAGE)

Even after clicking on the download button and after getting the Log output saying "File is directly downloaded to folder supposedly...", I am still not finding the image in my downloads directory.


Solution

  • Use this code to save in the gallery :

        fun saveImage(image: Bitmap, url:(String) -> Unit): String? {
        var savedImagePath: String? = null
        val imageFileName = "JPEG_" + UUID.randomUUID().toString() + ".jpg"
        val storageDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                .toString() + "/zigap"
        )
        var success = true
        if (!storageDir.exists()) {
            success = storageDir.mkdirs()
        }
        if (success) {
            val imageFile = File(storageDir, imageFileName)
            savedImagePath = imageFile.absolutePath
            try {
                val fOut: OutputStream = FileOutputStream(imageFile)
                image.compress(Bitmap.CompressFormat.JPEG, 100, fOut)
                fOut.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
    
            // Add the image to the system gallery
            url(savedImagePath)
            galleryAddPic(savedImagePath)
            //Toast.makeText(this, "IMAGE SAVED", Toast.LENGTH_LONG).show() // to make this working, need to manage coroutine, as this execution is something off the main thread
        }
        return savedImagePath
    }
    
    private fun galleryAddPic(imagePath: String?) {
        imagePath?.let { path ->
            val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
            val f = File(path)
            val contentUri: Uri = Uri.fromFile(f)
            mediaScanIntent.data = contentUri
            MainRepository.application.sendBroadcast(mediaScanIntent)
        }
    }