In android API 28 view.getDrawingCache()
has been deprecated. Is there any newer solution to generate a Bitmap of a particular view in android.
Asked
Active
Viewed 4.2k times
48

Ashvin solanki
- 4,802
- 3
- 25
- 65

Mostafa Monowar
- 881
- 1
- 8
- 14
8 Answers
74
Two ways to get bitmap of view
- Using Canvas
- Using Pixel Api
Canvas Java
Bitmap getBitmapFromView(View view) {
Bitmap bitmap = Bitmap.createBitmap(
view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
Bitmap getBitmapFromView(View view,int defaultColor) {
Bitmap bitmap = Bitmap.createBitmap(
view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(defaultColor);
view.draw(canvas);
return bitmap;
}
Canvas Kotlin
fun getBitmapFromView(view: View): Bitmap {
val bitmap = Bitmap.createBitmap(
view.width, view.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
view.draw(canvas)
return bitmap
}
fun getBitmapFromView(view: View, defaultColor: Int): Bitmap {
val bitmap = Bitmap.createBitmap(
view.width, view.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
canvas.drawColor(defaultColor)
view.draw(canvas)
return bitmap
}
Example
//@param rootView is View object which you want to get bitmap
Bitmap bitmap = getBitmapFromView(rootView);
Bitmap bitmapColored = getBitmapFromView(rootView,Color.WHITE);
PixelCopy Api
https://stackoverflow.com/a/52985554/9909365
fun getBitmapFromView(view: View, activity: Activity, callback: (Bitmap) -> Unit) {
activity.window?.let { window ->
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
callback(bitmap)
}
// possible to handle other result codes ...
}, Handler())
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace()
}
}
}
For More See About

hata
- 11,633
- 6
- 46
- 69

Ashvin solanki
- 4,802
- 3
- 25
- 65
-
how can I get portion of view. createBitmap seems to take only width and height, looking for x,y,width,height – Alex Feb 22 '19 at 16:40
-
@Alex user this `Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)` – Ashvin solanki Feb 23 '19 at 04:54
-
and how do you get source now. Bcz view.getDrawingCache() is deprecated which was returning bitmap. – Alex Feb 23 '19 at 20:51
-
@Alex first use this method to get bitmap of view the modify as u need – Ashvin solanki Feb 24 '19 at 12:47
-
kotlin has a View.drawToBitmap extension function, which takes scrollX/Y into consideration – Xixiaxixi Aug 20 '23 at 02:41
14
I have found a way to use PixelCopy API for retrieving the view as a Bitmap. Used Kotlin
fun getBitmapFromView(view: View, activity: Activity, callback: (Bitmap) -> Unit) {
activity.window?.let { window ->
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
callback(bitmap)
}
// possible to handle other result codes ...
}, Handler())
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace()
}
}
}

Mostafa Monowar
- 881
- 1
- 8
- 14
-
[ref](https://developer.android.com/reference/android/view/PixelCopy#request(android.view.Window,%20android.graphics.Rect,%20android.graphics.Bitmap,%20android.view.PixelCopy.OnPixelCopyFinishedListener,%20android.os.Handler)) – olfek Feb 03 '19 at 16:00
-
23Why does Google always have to complicate things? I want the bitmap the same time I'm calling the method not later on in the future using callbacks. – TheRealChx101 Feb 10 '19 at 13:03
-
2@TheRealChx101 I found [this](https://stackoverflow.com/a/19383606/812919) today which I'm going to use instead. – olfek Feb 15 '19 at 23:30
-
1`PixelCopy` requires API Level 26 and above. If you want compatability, for older API level, use the solution posted by @daka. – Morgan Koh Mar 12 '19 at 08:02
-
1@daka you can use [link](https://github.com/Muddz/PixelShot) this library. It handles all stuffs for saving an image of a view. – Mostafa Monowar Mar 12 '19 at 10:56
-
3
Try this:
private fun convertViewToDrawable(view: View): Bitmap {
val spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
view.measure(spec, spec)
view.layout(0, 0, view.measuredWidth, view.measuredHeight)
val b = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight,
Bitmap.Config.ARGB_8888)
val c = Canvas(b)
c.translate((-view.scrollX).toFloat(), (-view.scrollY).toFloat())
view.draw(c)
return b
}

Shyam Kumar
- 909
- 11
- 12
-
-
Without it, if the view is scrolled, the part of the view that gets written to the bitmap will not match the part of the view that is actually visible. – Brian Rak Jul 18 '21 at 16:54
2
As of the official documentation getDrawingCache() you should use the PixelCopy api.

scienticious
- 438
- 1
- 7
- 22

Antonio Vlasic
- 337
- 3
- 15
-
Do I need to use SurfaceView to use PixelCopy(). Cause in android documentation it sayes "pixel copy requests to allow for copy operations from Surface to Bitmap". – Mostafa Monowar Oct 04 '18 at 10:02
-
-
1
-
how to use: https://medium.com/@hiteshkrsahu/a-complete-guide-for-taking-screenshot-in-android-28-bcb9a19a2b6e – Nick Kovalsky Sep 10 '20 at 06:58
-
The use of PixelCopy is not necessarily "should". The [docs](https://developer.android.com/reference/android/view/View.html#getDrawingCache()) only recommends using it for UI feedback report and unit tests. – mr5 Oct 10 '20 at 13:20
1
much precise code..
private fun convertViewToDrawable(view: View): Bitmap {
val b = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight,
Bitmap.Config.ARGB_8888)
val c = Canvas(b)
c.translate((-view.scrollX).toFloat(), (-view.scrollY).toFloat())
view.draw(c)
return b
}

Asad
- 1,241
- 3
- 19
- 32
0
Some other kotlin code (ScrollView case)
val ScrollView.bitmap: Bitmap
get() {
val bitmap = Bitmap.createBitmap(width, getChildAt(0).height, Bitmap.Config.RGB_565)
with(Canvas(bitmap)) {
val background = background
if (background != null) {
background.draw(this)
} else {
drawColor(Color.WHITE)
}
draw(this)
}
return bitmap
}

Vlad
- 7,997
- 3
- 56
- 43
0
bitmap = view.drawToBitmap()
val pixel = bitmap.getpixel(x,y)

Suraj Rao
- 29,388
- 11
- 94
- 103
-
While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch May 25 '22 at 05:52
0
Kotlin code with view inflation:
fun getBitmapFromView(layoutInflater: LayoutInflater): Bitmap =
layoutInflater.inflate(R.layout.layoutID, null).run {
//Bind data If you needed Example - [findViewById<TextView>(R.id.viewId).text = data]
measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
layout(0, 0, measuredWidth, measuredHeight)
val bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
draw(canvas)
bitmap
}
layoutInflater can be retrieved like,
Inside activity or fragment -
this.layoutInflaterOutside activity or fragment -
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

Shivanand Darur
- 3,158
- 1
- 26
- 32