@@ -17,7 +17,6 @@ import java.io.FileOutputStream
1717private const val TAG = " ScreenshotUtils"
1818private const val BOOKMARK_PREVIEWS_DIR = " bookmark_previews"
1919
20- // TODO: both methods are quite similar, need to merge them
2120object ScreenshotUtils {
2221
2322 /* *
@@ -34,33 +33,9 @@ object ScreenshotUtils {
3433 topCropDp : Int = 110
3534 ): ImageBitmap ? {
3635 return try {
37- val bitmap = view.drawToBitmap()
38-
39- // TODO: calculate this dynamically somehow? Hardcode doesn't feel right
40- val topCropHeight = with (density) { topCropDp.dp.toPx() }.toInt()
41-
42- val croppedBitmap = if (bitmap.height > topCropHeight) {
43- Bitmap .createBitmap(
44- bitmap,
45- 0 ,
46- topCropHeight,
47- bitmap.width,
48- bitmap.height - topCropHeight
49- )
50- } else {
51- bitmap
52- }
53-
54- val scaledBitmap = croppedBitmap.scale(
55- croppedBitmap.width / 4 ,
56- croppedBitmap.height / 4
57- )
58-
36+ val scaledBitmap = captureAndCrop(view, density, topCropDp) ? : return null
5937 val result = scaledBitmap.asImageBitmap()
60-
61- if (bitmap != croppedBitmap) bitmap.recycle()
62- if (croppedBitmap != scaledBitmap) croppedBitmap.recycle()
63-
38+ // Don't recycle — asImageBitmap() wraps the bitmap
6439 result
6540 } catch (e: Exception ) {
6641 Log .e(TAG , " Failed to capture screenshot" , e)
@@ -79,26 +54,7 @@ object ScreenshotUtils {
7954 bookmarkId : String
8055 ): String? {
8156 return try {
82- val bitmap = view.drawToBitmap()
83-
84- // TODO: calculate this dynamically somehow? Hardcode doesn't feel right
85- val topCropHeight = with (density) { 110 .dp.toPx() }.toInt()
86- val croppedBitmap = if (bitmap.height > topCropHeight) {
87- Bitmap .createBitmap(
88- bitmap,
89- 0 ,
90- topCropHeight,
91- bitmap.width,
92- bitmap.height - topCropHeight
93- )
94- } else {
95- bitmap
96- }
97-
98- val scaledBitmap = croppedBitmap.scale(
99- croppedBitmap.width / 4 ,
100- croppedBitmap.height / 4
101- )
57+ val scaledBitmap = captureAndCrop(view, density, 110 ) ? : return null
10258
10359 val dir = File (context.filesDir, BOOKMARK_PREVIEWS_DIR )
10460 if (! dir.exists()) dir.mkdirs()
@@ -107,10 +63,6 @@ object ScreenshotUtils {
10763 FileOutputStream (file).use { out ->
10864 scaledBitmap.compress(Bitmap .CompressFormat .JPEG , 80 , out )
10965 }
110-
111- // Cleanup
112- if (bitmap != croppedBitmap) bitmap.recycle()
113- if (croppedBitmap != scaledBitmap) croppedBitmap.recycle()
11466 scaledBitmap.recycle()
11567
11668 file.absolutePath
@@ -120,6 +72,38 @@ object ScreenshotUtils {
12072 }
12173 }
12274
75+ /* *
76+ * Captures a view, crops the top area, and scales down by 4x.
77+ * Caller manages the returned bitmap's lifecycle.
78+ */
79+ private fun captureAndCrop (view : View , density : Density , topCropDp : Int ): Bitmap ? {
80+ val bitmap = view.drawToBitmap()
81+ // TODO: calculate this dynamically somehow? Hardcode doesn't feel right
82+ val topCropHeight = with (density) { topCropDp.dp.toPx() }.toInt()
83+
84+ val croppedBitmap = if (bitmap.height > topCropHeight) {
85+ Bitmap .createBitmap(
86+ bitmap,
87+ 0 ,
88+ topCropHeight,
89+ bitmap.width,
90+ bitmap.height - topCropHeight
91+ )
92+ } else {
93+ bitmap
94+ }
95+
96+ val scaledBitmap = croppedBitmap.scale(
97+ croppedBitmap.width / 4 ,
98+ croppedBitmap.height / 4
99+ )
100+
101+ if (bitmap != croppedBitmap) bitmap.recycle()
102+ if (croppedBitmap != scaledBitmap) croppedBitmap.recycle()
103+
104+ return scaledBitmap
105+ }
106+
123107 /* *
124108 * Loads a bookmark preview from storage
125109 */
0 commit comments