1

I want a button to be clicked that saves an image view to the android devices gallery in kotlin. I have this

val image = findViewById<ImageView>(R.id.QRImage)
AK105
  • 53
  • 1
  • 8
  • `val image = ... ` That should be `val imageView = ...`. And you cannot store imageviews to the gallery but only imsges. – blackapps Jan 23 '22 at 04:33

3 Answers3

0

You can convert your image to bitmap first like the code below:

val image = findViewById<ImageView>(R.id.QRImage)
val imageBitmap = image.drawable.toBitmap()

Then save the bitmap where you want like the code below:

val fileOutputStream = FileOutputStream("Location") //location of the image 
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)

or save it directly like the code below:

 MediaStore.Images.Media.insertImage(context.contentResolver, imageBitmap, "Image title ", null)
0

I think, this should work: MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);

Also, it is written in this question: android - save image into gallery

G3nz0
  • 3
  • 2
  • Insert image is deprecated in java:70 am I still able to use it without issue? – AK105 Jan 23 '22 at 20:40
  • @AnshKarnwal - yes, it won't break anything, it's just an outdated way. but the documentation suggests using ContentValues ​​and MediaStore.isPending(). check this: https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#IS_PENDING and check this:https://stackoverflow.com/questions/57726896/mediastore-images-media-insertimage-deprecated – G3nz0 Jan 23 '22 at 21:09
0

Use the following function it's 100% working with target SDK 30+

fun insertImage(
    cr: ContentResolver,
    source: Bitmap?,
    title: String?,
    description: String?
): String? {
    val values = ContentValues()
    values.put(Images.Media.TITLE, title)
    values.put(Images.Media.DISPLAY_NAME, title)
    values.put(Images.Media.DESCRIPTION, description)
    values.put(Images.Media.MIME_TYPE, "image/jpeg")
    // Add the date meta data to ensure the image is added at the front of the gallery
    values.put(Images.Media.DATE_ADDED, System.currentTimeMillis())
    values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis())
    var url: Uri? = null
    var stringUrl: String? = null /* value to be returned */
    try {
        url = cr.insert(Images.Media.EXTERNAL_CONTENT_URI, values)
        if (source != null) {
            val imageOut = cr.openOutputStream(url!!)
            try {
                source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut)
            } finally {
                imageOut!!.close()
            }
            val id = ContentUris.parseId(url!!)
            // Wait until MINI_KIND thumbnail is generated.
            val miniThumb =
                Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null)
            // This is for backward compatibility.
            storeThumbnail(cr, miniThumb, id, 50f, 50f, Images.Thumbnails.MICRO_KIND)
        } else {
            cr.delete(url!!, null, null)
            url = null
        }
        Toast.makeText(this, "Image Saved to Gallery", Toast.LENGTH_LONG).show()
    } catch (e: Exception) {
        if (url != null) {
            cr.delete(url, null, null)
            url = null
        }
    }
    if (url != null) {
        stringUrl = url.toString()
    }
    return stringUrl
}

private fun storeThumbnail(
    cr: ContentResolver,
    source: Bitmap,
    id: Long,
    width: Float,
    height: Float,
    kind: Int
): Bitmap? {

    // create the matrix to scale it
    val matrix = Matrix()
    val scaleX = width / source.width
    val scaleY = height / source.height
    matrix.setScale(scaleX, scaleY)
    val thumb = Bitmap.createBitmap(
        source, 0, 0,
        source.width,
        source.height, matrix,
        true
    )
    val values = ContentValues(4)
    values.put(Images.Thumbnails.KIND, kind)
    values.put(Images.Thumbnails.IMAGE_ID, id.toInt())
    values.put(Images.Thumbnails.HEIGHT, thumb.height)
    values.put(Images.Thumbnails.WIDTH, thumb.width)
    val url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values)
    return try {
        val thumbOut = cr.openOutputStream(url!!)
        thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut)
        thumbOut!!.close()
        thumb
    } catch (ex: FileNotFoundException) {
        null
    } catch (ex: IOException) {
        null
    }
Michael
  • 411
  • 2
  • 6
  • 15