This code demonstrates how to adjust the opacity of a Bitmap image in an Android application written in Kotlin. It utilizes a SeekBar widget to allow users to interactively control the transparency level.
The code is divided into three main parts:
Activity Code (MainActivity.kt): This section handles the core functionality of the app. It retrieves references to UI elements like ImageViews, TextViews, and the SeekBar from the activity layout. Then, it loads a bitmap from the assets folder and displays it in the first ImageView. The key functionality lies in the
setOpacity
function, explained later. Finally, a SeekBar listener is implemented to capture user interaction and dynamically update the second ImageView with a modified version of the original bitmap having adjusted transparency based on the SeekBar position.Extension Functions: The code defines two extension functions. The first,
assetsToBitmap
, simplifies loading a bitmap image from the application's assets directory. The second,setOpacity
, is responsible for modifying the opacity of a given Bitmap.Layout (activity_main.xml): This file defines the user interface layout of the application using ConstraintLayout. It positions the ImageViews to display the original and modified bitmaps, a TextView to indicate their purpose, a SeekBar for user input, and another TextView to provide feedback on the selected opacity level.
Summary
This code provides a user-friendly way to adjust the transparency of an image in an Android app. Users can manipulate a SeekBar to control the opacity level, with visual feedback provided through the updated image and informative text displays. The code leverages extension functions to improve readability and maintainability.
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.widget.*
import java.io.IOException
import kotlin.math.roundToInt
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// get the widgets reference from XML layout
val imageView = findViewById<ImageView>(R.id.imageView)
val imageView2 = findViewById<ImageView>(R.id.imageView2)
val textView = findViewById<TextView>(R.id.textView)
val textView2 = findViewById<TextView>(R.id.textView2)
val seekBar = findViewById<SeekBar>(R.id.seekBar)
// get the bitmap from assets folder
val bitmap = assetsToBitmap("flower103.jpg")
bitmap?.apply {
// show original bitmap in first image view
imageView.setImageBitmap(this)
textView.text = "Original Bitmap"
seekBar.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar?,
progress: Int,
fromUser: Boolean
) {
// show the transparent bitmap in image view
imageView2.setImageBitmap(setOpacity(progress))
textView2.text = "Bitmap Opacity $progress%"
textView2.append("\n0% full transparent " +
"100% full opaque")
val alpha = (progress * 2.55).roundToInt()
textView2.append("\nAlpha value " +
"$alpha (Range 0..255)")
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
}
}
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName:String):Bitmap?{
return try {
val stream = assets.open(fileName)
BitmapFactory.decodeStream(stream)
} catch (e: IOException) {
e.printStackTrace()
null
}
}
// extension function to set bitmap opacity by percent
fun Bitmap.setOpacity(opacityPercent:Int):Bitmap?{
val bitmap = copy(Bitmap.Config.ARGB_8888,true)
// int: set the alpha component [0..255] of the paint's color.
// 0 is full transparent
// 255 is full opaque
val opacity = (opacityPercent * 2.55).roundToInt()
val color = opacity and 0xFF shl 24
Canvas(bitmap).drawColor(color, PorterDuff.Mode.DST_IN)
return bitmap
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootLayout"
android:background="#DCDCDC"
android:padding="24dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="225dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Original Bitmap"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="225dp"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:max="100"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView2" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Transparent Bitmap"
app:layout_constraintEnd_toEndOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="@+id/imageView2"
app:layout_constraintTop_toBottomOf="@+id/seekBar" />
</androidx.constraintlayout.widget.ConstraintLayout>