Skip to content

Commit d733aba

Browse files
committed
Fix image
1 parent 6e45631 commit d733aba

File tree

6 files changed

+62
-45
lines changed

6 files changed

+62
-45
lines changed

app/src/main/java/omega_r/com/omegatypesexample/MainActivity.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import kotlinx.coroutines.Dispatchers
1919
import kotlinx.coroutines.launch
2020
import kotlinx.coroutines.withContext
2121
import java.io.ByteArrayOutputStream
22+
import kotlin.concurrent.thread
2223

2324

2425
class MainActivity : BaseActivity() {
@@ -29,8 +30,6 @@ class MainActivity : BaseActivity() {
2930
override fun onCreate(savedInstanceState: Bundle?) {
3031
super.onCreate(savedInstanceState)
3132

32-
GlideImagesProcessor.setGlideBitmapPool(this)
33-
3433
setContentView(R.layout.activity_main)
3534
val text = Text.from("test ") +
3635
Text.from(
@@ -77,6 +76,8 @@ class MainActivity : BaseActivity() {
7776

7877
imageView.setImage(image)
7978

79+
80+
8081
// thread {
8182
// val stream = image.getStream(this, Bitmap.CompressFormat.PNG)
8283
// val bitmap = BitmapFactory.decodeStream(stream)

omegatypes/src/main/java/com/omega_r/libs/omegatypes/decoders/SimpleBitmapDecoders.kt

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ package com.omega_r.libs.omegatypes.decoders
33
import android.graphics.Bitmap
44
import android.graphics.BitmapFactory
55
import android.os.Build
6+
import java.io.BufferedInputStream
67
import java.io.File
78
import java.io.InputStream
89

910

1011
/**
1112
* Created by Anton Knyazev on 2019-10-09.
1213
*/
14+
private const val MARK_POSITION = 5 * 1024 * 1024
15+
1316
open class SimpleBitmapDecoders(protected val bitmapPool: BitmapPool) : BitmapDecoders {
1417

1518
override fun decodeBitmap(source: File, requiredWidth: Int?, requiredHeight: Int?): Bitmap? {
@@ -19,8 +22,13 @@ open class SimpleBitmapDecoders(protected val bitmapPool: BitmapPool) : BitmapDe
1922
}
2023

2124
override fun decodeBitmap(source: InputStream, requiredWidth: Int?, requiredHeight: Int?): Bitmap? {
25+
val stream = if (!source.markSupported()) BufferedInputStream(source) else source
26+
stream.mark(MARK_POSITION)
27+
2228
return decodeBitmap(requiredWidth, requiredHeight) {
23-
BitmapFactory.decodeStream(source, null, it)
29+
BitmapFactory.decodeStream(stream, null, it).also {
30+
stream.reset()
31+
}
2432
}
2533
}
2634

@@ -42,31 +50,38 @@ open class SimpleBitmapDecoders(protected val bitmapPool: BitmapPool) : BitmapDe
4250
bitmapPool.trimMemory(level)
4351
}
4452

45-
protected inline fun decodeBitmap(reqWidth: Int?, reqHeight: Int?, bitmapFactory: (BitmapFactory.Options) -> Bitmap?): Bitmap? {
53+
protected inline fun decodeBitmap(reqWidth: Int?, reqHeight: Int?, decoder: (BitmapFactory.Options) -> Bitmap?): Bitmap? {
4654
val options = BitmapFactory.Options()
4755

48-
val inBitmap = if (reqWidth != null && reqHeight != null) {
49-
options.inJustDecodeBounds = true
50-
bitmapFactory(options)
51-
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
52-
options.inJustDecodeBounds = false
56+
if (reqWidth != null && reqHeight != null) {
57+
val tryOptions = BitmapFactory.Options()
58+
tryOptions.inJustDecodeBounds = true
59+
decoder(tryOptions)
60+
options.inSampleSize = calculateInSampleSize(tryOptions, reqWidth, reqHeight)
61+
tryOptions.inSampleSize = options.inSampleSize
5362
options.inMutable = true
54-
bitmapPool.getBitmap(options.outWidth, options.outHeight, options.inPreferredConfig)
63+
val inBitmap = bitmapPool.getBitmap(tryOptions.outWidth, tryOptions.outHeight, tryOptions.inPreferredConfig)
64+
65+
if (inBitmap != null && canUseForInBitmap(inBitmap, tryOptions)) {
66+
options.inBitmap = inBitmap
67+
}
5568
} else {
5669
options.inMutable = true
5770
options.inSampleSize = 1
58-
null
59-
}
60-
61-
if (inBitmap != null && canUseForInBitmap(inBitmap, options)) {
62-
options.inBitmap = inBitmap
6371
}
6472

6573
return try {
66-
bitmapFactory(options)
74+
val bitmap = decoder(options)
75+
bitmap
6776
} catch (e: Exception) {
68-
options.inBitmap = null
69-
bitmapFactory(options)
77+
e.printStackTrace()
78+
options.inBitmap ?.let {
79+
bitmapPool.putBitmap(it)
80+
options.inBitmap = null
81+
}
82+
83+
val bitmap = decoder(options)
84+
bitmap
7085
}
7186
}
7287

omegatypes/src/main/java/com/omega_r/libs/omegatypes/image/BaseBitmapImage.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.graphics.Bitmap
55
import android.graphics.drawable.BitmapDrawable
66
import android.view.View
77
import android.widget.ImageView
8+
import com.omega_r.libs.omegatypes.decoders.BitmapDecoders
89
import com.omega_r.libs.omegatypes.tools.ImageAsyncExecutor.Companion.executeImageAsync
910
import com.omega_r.libs.omegatypes.tools.ImageSizeExtractor
1011
import com.omega_r.libs.omegatypes.tools.getScaledBitmap
@@ -13,6 +14,7 @@ import kotlinx.coroutines.launch
1314
import kotlinx.coroutines.withContext
1415
import java.io.InputStream
1516
import java.lang.ref.WeakReference
17+
import java.util.*
1618

1719
/**
1820
* Created by Anton Knyazev on 2019-10-03.
@@ -22,24 +24,27 @@ abstract class BaseBitmapImage : Image() {
2224
abstract class Processor<I : BaseBitmapImage>(private val autoRecycle: Boolean) : ImageProcessor<I>() {
2325

2426
override fun I.applyImageInner(imageView: ImageView, placeholderResId: Int) {
25-
val width = imageView.width
26-
val height = imageView.height
27-
2827
if (placeholderResId != NO_PLACEHOLDER_RES) {
2928
imageView.setImageResource(placeholderResId)
29+
} else {
30+
imageView.setImageDrawable(null)
3031
}
3132

33+
val width = imageView.width
34+
val height = imageView.height
35+
36+
3237
if (width <= 0 || height <= 0) {
3338
ImageSizeExtractor(imageView) { target ->
3439
applyImageInner(target, placeholderResId)
3540
}
3641
} else {
3742
val imageScaleType = imageView.scaleType
38-
executeImageAsync(imageView) { context ->
43+
executeImageAsync(imageView, extractor = { context ->
3944
getBitmap(context, this, width, height)?.run {
4045
getScaledBitmap(width, height, imageScaleType, autoRecycle, this)
4146
}
42-
}
47+
}, setter = ImageView::setImageBitmap)
4348
}
4449
}
4550

@@ -50,7 +55,6 @@ abstract class BaseBitmapImage : Image() {
5055
ImageProcessors.current.launch {
5156
val view1 = viewWeak.get() ?: return@launch
5257
val bitmap = getBitmap(view1.context, this@applyBackgroundInner, null)
53-
5458
withContext(Dispatchers.Main) {
5559
val view2 = viewWeak.get() ?: return@withContext
5660
Image.Processor.applyBackground(view2, bitmap?.let { BitmapDrawable(view2.resources, it) })
@@ -66,8 +70,8 @@ abstract class BaseBitmapImage : Image() {
6670
return@withContext bitmap
6771
.toInputStream(compressFormat, quality)
6872
} finally {
69-
if (autoRecycle) {
70-
bitmap?.recycle()
73+
if (autoRecycle && bitmap != null) {
74+
BitmapDecoders.current.recycle(bitmap)
7175
}
7276
}
7377
}

omegatypes/src/main/java/com/omega_r/libs/omegatypes/image/Image.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import android.os.Build
99
import android.view.View
1010
import android.widget.ImageView
1111
import android.widget.TextView
12+
import com.omega_r.libs.omegatypes.decoders.BitmapDecoders
1213
import kotlinx.coroutines.withContext
1314
import java.io.InputStream
1415
import java.io.Serializable

omegatypes/src/main/java/com/omega_r/libs/omegatypes/image/UrlImage.kt

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,21 @@ data class UrlImage(val url: String) : BaseBitmapImage() {
2626

2727
override suspend fun getBitmap(context: Context, image: UrlImage, width: Int?, height: Int?): Bitmap? {
2828

29-
return try {
30-
val bytes = image.getBytes().inputStream()
31-
bytes.toBitmap(width, height)
32-
} catch (e: IOException) {
33-
null
34-
}
35-
}
36-
37-
38-
private fun UrlImage.getBytes(): ByteArray {
3929
var connection: HttpURLConnection? = null
40-
try {
41-
connection = URL(url).openConnection() as HttpURLConnection
30+
return try {
31+
connection = URL(image.url).openConnection() as HttpURLConnection
4232
connection.doInput = true;
4333
connection.connect()
44-
val input = connection.inputStream
45-
return input.readBytes()
34+
connection.inputStream
35+
.toBitmap(width, height)
36+
} catch (e: IOException) {
37+
e.printStackTrace()
38+
null
4639
} finally {
4740
connection?.disconnect()
4841
}
4942
}
5043

51-
5244
}
5345

5446

omegatypes/src/main/java/com/omega_r/libs/omegatypes/tools/ImageAsyncExecutor.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ import java.util.*
1111
/**
1212
* Created by Anton Knyazev on 2019-10-02.
1313
*/
14-
class ImageAsyncExecutor(imageView: ImageView, private val extractor: suspend (Context) -> Bitmap?) : AsyncTask<Void, Void, Bitmap?>() {
14+
class ImageAsyncExecutor(
15+
imageView: ImageView,
16+
private val extractor: suspend (Context) -> Bitmap?,
17+
private val setter: (ImageView, Bitmap) -> Unit
18+
) : AsyncTask<Void, Void, Bitmap?>() {
1519

1620
companion object {
1721

1822
private val imageAsyncExecutors = WeakHashMap<ImageView, ImageAsyncExecutor>()
1923

20-
fun executeImageAsync(imageView: ImageView, extractor: suspend (Context) -> Bitmap?): ImageAsyncExecutor {
21-
return ImageAsyncExecutor(imageView, extractor)
24+
fun executeImageAsync(imageView: ImageView, extractor: suspend (Context) -> Bitmap?, setter: (ImageView, Bitmap) -> Unit): ImageAsyncExecutor {
25+
return ImageAsyncExecutor(imageView, extractor, setter)
2226
.apply {
2327
execute()
2428
}
@@ -45,7 +49,7 @@ class ImageAsyncExecutor(imageView: ImageView, private val extractor: suspend (C
4549
val imageView = imageView.get() ?: return
4650
this.imageView.clear()
4751
if (result != null) {
48-
imageView.setImageBitmap(result)
52+
setter(imageView, result)
4953
}
5054
imageAsyncExecutors.remove(imageView)
5155
}

0 commit comments

Comments
 (0)