From ef0450ecf217b8a9e5c5cbecefe03d99342c33e9 Mon Sep 17 00:00:00 2001 From: Acclorite <140836141+Acclorite@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:01:42 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=20Optimize=20Image=20comp?= =?UTF-8?q?ression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Dynamic image compression based on file size (slightly reduces memory consumption) --- .../book_story/data/parser/DocumentParser.kt | 57 +++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt index e2f96160..c58f1f57 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt @@ -106,27 +106,13 @@ class DocumentParser @Inject constructor( src == image.name.substringAfterLast('/').lowercase() } ?: return@forEach - zipFile?.getInputStream(imageEntry)?.use { inputStream -> - val options = BitmapFactory.Options().apply { - inSampleSize = 2 - inPreferredConfig = Bitmap.Config.RGB_565 - } - BitmapFactory.decodeStream( - /* is = */ inputStream, - /* outPadding = */ null, - /* opts = */ options - )?.asImageBitmap() - } + zipFile?.getImage(imageEntry)?.asImageBitmap() } catch (e: Exception) { e.printStackTrace() - return@forEach - } + null + } ?: return@forEach - if (image == null) return@forEach - - // Optimize image.prepareToDraw() - readerText.add( // Adding image ReaderText.Image( imageBitmap = image @@ -178,4 +164,41 @@ class DocumentParser @Inject constructor( return readerText } + + /** + * Getting bitmap from [ZipFile] with compression + * that depends on the [imageEntry] size. + */ + private fun ZipFile.getImage(imageEntry: ZipEntry): Bitmap? { + fun getBitmapFromInputStream(compressionLevel: Int = 1): Bitmap? { + return getInputStream(imageEntry).use { inputStream -> + BitmapFactory.decodeStream( + inputStream, + null, + BitmapFactory.Options().apply { + inPreferredConfig = Bitmap.Config.RGB_565 + inSampleSize = compressionLevel + } + ) + } + } + + + val uncompressedBitmap = getBitmapFromInputStream() ?: return null + return when (uncompressedBitmap.byteCount) { + in 0..1048576 /* 0 - 1MB */ -> { + uncompressedBitmap + } + + in 1048576..2097152 /* 1MB - 2MB */ -> { + uncompressedBitmap.recycle() + getBitmapFromInputStream(2) + } + + else -> /* >=2MB */ { + uncompressedBitmap.recycle() + getBitmapFromInputStream(3) + } + } + } } \ No newline at end of file