Add option to choose animation drawable bitmap format.
Add a forgotten inputstream.close()
This commit is contained in:
parent
7657c0e505
commit
4cb330d522
|
@ -51,13 +51,15 @@ class ApngDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
||||||
|
* @param context Context needed for the animation drawable
|
||||||
* @param inStream Input Stream to decode. Will be close at the end.
|
* @param inStream Input Stream to decode. Will be close at the end.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun decodeApng(context: Context, inStream: InputStream, speed: Float = 1f): Drawable {
|
fun decodeApng(context: Context, inStream: InputStream, speed: Float = 1f, config : Bitmap.Config = Bitmap.Config.ARGB_8888): Drawable {
|
||||||
val inputStream = BufferedInputStream(inStream)
|
val inputStream = BufferedInputStream(inStream)
|
||||||
val bytes = ByteArray(8)
|
val bytes = ByteArray(8)
|
||||||
inputStream.mark(0)
|
inputStream.mark(0)
|
||||||
|
@ -197,7 +199,11 @@ class ApngDecoder {
|
||||||
drawable.addFrame(
|
drawable.addFrame(
|
||||||
BitmapDrawable(
|
BitmapDrawable(
|
||||||
context.resources,
|
context.resources,
|
||||||
btm
|
if (btm.config != config) {
|
||||||
|
btm.copy(config, btm.isMutable)
|
||||||
|
} else {
|
||||||
|
btm
|
||||||
|
}
|
||||||
),
|
),
|
||||||
(delay / speed).toInt()
|
(delay / speed).toInt()
|
||||||
)
|
)
|
||||||
|
@ -299,7 +305,11 @@ class ApngDecoder {
|
||||||
drawable.addFrame(
|
drawable.addFrame(
|
||||||
BitmapDrawable(
|
BitmapDrawable(
|
||||||
context.resources,
|
context.resources,
|
||||||
btm
|
if (btm.config != config) {
|
||||||
|
btm.copy(config, btm.isMutable)
|
||||||
|
} else {
|
||||||
|
btm
|
||||||
|
}
|
||||||
),
|
),
|
||||||
(delay / speed).toInt()
|
(delay / speed).toInt()
|
||||||
)
|
)
|
||||||
|
@ -451,87 +461,97 @@ class ApngDecoder {
|
||||||
val source = ImageDecoder.createSource(buf)
|
val source = ImageDecoder.createSource(buf)
|
||||||
ImageDecoder.decodeDrawable(source)
|
ImageDecoder.decodeDrawable(source)
|
||||||
} else {
|
} else {
|
||||||
Drawable.createFromStream(
|
val drawable = Drawable.createFromStream(
|
||||||
inputStream,
|
inputStream,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
inputStream.close()
|
||||||
|
drawable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
||||||
* @param context Context.
|
* @param context Context needed for animation drawable.
|
||||||
* @param file File to decode.
|
* @param file File to decode.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun decodeApng(context: Context, file: File, speed: Float = 1f): Drawable =
|
fun decodeApng(context: Context, file: File, speed: Float = 1f, config : Bitmap.Config = Bitmap.Config.ARGB_8888): Drawable =
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
FileInputStream(file), speed
|
FileInputStream(file), speed, config
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
||||||
* @param context Context is needed for contentResolver.
|
* @param context Context is needed for contentResolver and animation drawable.
|
||||||
* @param uri Uri to open.
|
* @param uri Uri to open.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun decodeApng(context: Context, uri: Uri, speed: Float = 1f): Drawable {
|
fun decodeApng(context: Context, uri: Uri, speed: Float = 1f, config : Bitmap.Config = Bitmap.Config.ARGB_8888): Drawable {
|
||||||
val inputStream = context.contentResolver.openInputStream(uri)
|
val inputStream = context.contentResolver.openInputStream(uri)
|
||||||
?: throw Exception("Failed to open InputStream, InputStream is null")
|
?: throw Exception("Failed to open InputStream, InputStream is null")
|
||||||
return decodeApng(
|
return decodeApng(
|
||||||
context,
|
context,
|
||||||
inputStream,
|
inputStream,
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
||||||
* @param context Context is needed for contentResolver.
|
* @param context Context is needed for contentResolver and animation drawable.
|
||||||
* @param res Resource to decode.
|
* @param res Resource to decode.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun decodeApng(context: Context, @RawRes res: Int, speed: Float = 1f): Drawable =
|
fun decodeApng(context: Context, @RawRes res: Int, speed: Float = 1f, config : Bitmap.Config = Bitmap.Config.ARGB_8888): Drawable =
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
context.resources.openRawResource(res),
|
context.resources.openRawResource(res),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
* Decode Apng and return a Drawable who can be an [AnimationDrawable] if it end successfully. Can also be an [android.graphics.drawable.AnimatedImageDrawable].
|
||||||
* @param context Context is needed for contentResolver.
|
* @param context Context is needed for contentResolver and animation drawable.
|
||||||
* @param url URL to decode.
|
* @param url URL to decode.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
suspend fun decodeApng(context: Context, url: URL, speed: Float = 1f) =
|
suspend fun decodeApng(context: Context, url: URL, speed: Float = 1f, config : Bitmap.Config = Bitmap.Config.ARGB_8888) =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
FileInputStream(
|
FileInputStream(
|
||||||
Loader.load(context, url)
|
Loader.load(context, url)
|
||||||
),
|
),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Apng into an imageView, asynchronously.
|
* Load Apng into an imageView, asynchronously.
|
||||||
* @param context Context.
|
* @param context Context needed for animation drawable.
|
||||||
* @param file File to decode.
|
* @param file File to decode.
|
||||||
* @param imageView Image View.
|
* @param imageView Image View.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
* @param callback [ApngDecoder.Callback] to handle success and error.
|
* @param callback [ApngDecoder.Callback] to handle success and error.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -541,7 +561,8 @@ class ApngDecoder {
|
||||||
file: File,
|
file: File,
|
||||||
imageView: ImageView,
|
imageView: ImageView,
|
||||||
speed: Float = 1f,
|
speed: Float = 1f,
|
||||||
callback: Callback? = null
|
callback: Callback? = null,
|
||||||
|
config : Bitmap.Config = Bitmap.Config.ARGB_8888
|
||||||
) {
|
) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -549,7 +570,8 @@ class ApngDecoder {
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
FileInputStream(file),
|
FileInputStream(file),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
imageView.setImageDrawable(drawable)
|
imageView.setImageDrawable(drawable)
|
||||||
|
@ -569,11 +591,12 @@ class ApngDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Apng into an imageView, asynchronously.
|
* Load Apng into an imageView, asynchronously.
|
||||||
* @param context Context.
|
* @param context Context needed for animation drawable and content resolver.
|
||||||
* @param uri Uri to load.
|
* @param uri Uri to load.
|
||||||
* @param imageView Image View.
|
* @param imageView Image View.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
* @param callback [ApngDecoder.Callback] to handle success and error.
|
* @param callback [ApngDecoder.Callback] to handle success and error.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -583,7 +606,8 @@ class ApngDecoder {
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
imageView: ImageView,
|
imageView: ImageView,
|
||||||
speed: Float = 1f,
|
speed: Float = 1f,
|
||||||
callback: Callback? = null
|
callback: Callback? = null,
|
||||||
|
config : Bitmap.Config = Bitmap.Config.ARGB_8888
|
||||||
) {
|
) {
|
||||||
val inputStream = context.contentResolver.openInputStream(uri)
|
val inputStream = context.contentResolver.openInputStream(uri)
|
||||||
?: throw Exception("Failed to open InputStream, InputStream is null")
|
?: throw Exception("Failed to open InputStream, InputStream is null")
|
||||||
|
@ -593,7 +617,8 @@ class ApngDecoder {
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
inputStream,
|
inputStream,
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
imageView.setImageDrawable(drawable)
|
imageView.setImageDrawable(drawable)
|
||||||
|
@ -613,11 +638,12 @@ class ApngDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Apng into an imageView, asynchronously.
|
* Load Apng into an imageView, asynchronously.
|
||||||
* @param context Context.
|
* @param context Context needed to decode the resource and for the animation drawable.
|
||||||
* @param res Raw resource to load.
|
* @param res Raw resource to load.
|
||||||
* @param imageView Image View.
|
* @param imageView Image View.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
* @param callback [ApngDecoder.Callback] to handle success and error.
|
* @param callback [ApngDecoder.Callback] to handle success and error.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -626,7 +652,8 @@ class ApngDecoder {
|
||||||
context: Context, @RawRes res: Int,
|
context: Context, @RawRes res: Int,
|
||||||
imageView: ImageView,
|
imageView: ImageView,
|
||||||
speed: Float = 1f,
|
speed: Float = 1f,
|
||||||
callback: Callback? = null
|
callback: Callback? = null,
|
||||||
|
config : Bitmap.Config = Bitmap.Config.ARGB_8888
|
||||||
) {
|
) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -634,7 +661,8 @@ class ApngDecoder {
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
context.resources.openRawResource(res),
|
context.resources.openRawResource(res),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
imageView.setImageDrawable(drawable)
|
imageView.setImageDrawable(drawable)
|
||||||
|
@ -655,11 +683,12 @@ class ApngDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Apng into an imageView, asynchronously.
|
* Load Apng into an imageView, asynchronously.
|
||||||
* @param context Context.
|
* @param context Context needed for the animation drawable.
|
||||||
* @param url URL to load.
|
* @param url URL to load.
|
||||||
* @param imageView Image View.
|
* @param imageView Image View.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
* @param callback [ApngDecoder.Callback] to handle success and error.
|
* @param callback [ApngDecoder.Callback] to handle success and error.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -669,7 +698,8 @@ class ApngDecoder {
|
||||||
url: URL,
|
url: URL,
|
||||||
imageView: ImageView,
|
imageView: ImageView,
|
||||||
speed: Float = 1f,
|
speed: Float = 1f,
|
||||||
callback: Callback? = null
|
callback: Callback? = null,
|
||||||
|
config : Bitmap.Config = Bitmap.Config.ARGB_8888
|
||||||
) {
|
) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -682,7 +712,8 @@ class ApngDecoder {
|
||||||
url
|
url
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
imageView.setImageDrawable(drawable)
|
imageView.setImageDrawable(drawable)
|
||||||
|
@ -702,11 +733,12 @@ class ApngDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Apng into an imageView, asynchronously.
|
* Load Apng into an imageView, asynchronously.
|
||||||
* @param context Context.
|
* @param context Context needed for decoding the image and creating the animation drawable.
|
||||||
* @param string URL to load
|
* @param string URL to load
|
||||||
* @param imageView Image View.
|
* @param imageView Image View.
|
||||||
* @param speed Optional parameter.
|
* @param speed Optional parameter.
|
||||||
* @param callback [ApngDecoder.Callback] to handle success and error.
|
* @param callback [ApngDecoder.Callback] to handle success and error.
|
||||||
|
* @param config Configuration applied to the bitmap added to the animation. Please note that the frame is decoded in ARGB_8888 and converted after, for the buffer.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -716,7 +748,8 @@ class ApngDecoder {
|
||||||
string: String,
|
string: String,
|
||||||
imageView: ImageView,
|
imageView: ImageView,
|
||||||
speed: Float = 1f,
|
speed: Float = 1f,
|
||||||
callback: Callback? = null
|
callback: Callback? = null,
|
||||||
|
config : Bitmap.Config = Bitmap.Config.ARGB_8888
|
||||||
) {
|
) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -726,7 +759,8 @@ class ApngDecoder {
|
||||||
URL(string),
|
URL(string),
|
||||||
imageView,
|
imageView,
|
||||||
speed,
|
speed,
|
||||||
callback
|
callback,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
} else if (File(string).exists()) {
|
} else if (File(string).exists()) {
|
||||||
var pathToLoad =
|
var pathToLoad =
|
||||||
|
@ -737,14 +771,16 @@ class ApngDecoder {
|
||||||
Uri.parse(pathToLoad),
|
Uri.parse(pathToLoad),
|
||||||
imageView,
|
imageView,
|
||||||
speed,
|
speed,
|
||||||
callback
|
callback,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
} else if (string.startsWith("file://android_asset/")) {
|
} else if (string.startsWith("file://android_asset/")) {
|
||||||
val drawable =
|
val drawable =
|
||||||
decodeApng(
|
decodeApng(
|
||||||
context,
|
context,
|
||||||
context.assets.open(string.replace("file:///android_asset/", "")),
|
context.assets.open(string.replace("file:///android_asset/", "")),
|
||||||
speed
|
speed,
|
||||||
|
config
|
||||||
)
|
)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
imageView.setImageDrawable(drawable)
|
imageView.setImageDrawable(drawable)
|
||||||
|
|
Loading…
Reference in New Issue