Add ApngAnimatorOptions and move oupson.apng.Utils to oupson.apng.utils.Utils
This commit is contained in:
parent
351ee29639
commit
6c46efc929
|
@ -1,12 +1,13 @@
|
|||
package oupson.apng
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import oupson.apng.Utils.Companion.isApng
|
||||
import oupson.apng.Utils.Companion.pngSignature
|
||||
import oupson.apng.Utils.Companion.to4Bytes
|
||||
import oupson.apng.utils.Utils.Companion.isApng
|
||||
import oupson.apng.utils.Utils.Companion.pngSignature
|
||||
import oupson.apng.utils.Utils.Companion.to4Bytes
|
||||
import oupson.apng.chunks.IHDR
|
||||
import oupson.apng.chunks.fcTL
|
||||
import oupson.apng.exceptions.NotApngException
|
||||
import oupson.apng.utils.Utils
|
||||
import java.util.zip.CRC32
|
||||
|
||||
class APNGDisassembler {
|
||||
|
|
|
@ -3,14 +3,15 @@ package oupson.apng
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import oupson.apng.ImageUtils.PnnQuantizer
|
||||
import oupson.apng.Utils.Companion.getBlend_op
|
||||
import oupson.apng.Utils.Companion.getDispose_op
|
||||
import oupson.apng.Utils.Companion.pngSignature
|
||||
import oupson.apng.Utils.Companion.to2Bytes
|
||||
import oupson.apng.Utils.Companion.to4Bytes
|
||||
import oupson.apng.Utils.Companion.toByteArray
|
||||
import oupson.apng.utils.Utils.Companion.getBlend_op
|
||||
import oupson.apng.utils.Utils.Companion.getDispose_op
|
||||
import oupson.apng.utils.Utils.Companion.pngSignature
|
||||
import oupson.apng.utils.Utils.Companion.to2Bytes
|
||||
import oupson.apng.utils.Utils.Companion.to4Bytes
|
||||
import oupson.apng.utils.Utils.Companion.toByteArray
|
||||
import oupson.apng.chunks.IDAT
|
||||
import oupson.apng.exceptions.NoFrameException
|
||||
import oupson.apng.utils.Utils
|
||||
import java.util.zip.CRC32
|
||||
|
||||
|
||||
|
|
|
@ -6,10 +6,13 @@ import android.graphics.*
|
|||
import android.net.Uri
|
||||
import android.widget.ImageView
|
||||
import org.jetbrains.anko.doAsync
|
||||
import org.jetbrains.anko.image
|
||||
import org.jetbrains.anko.runOnUiThread
|
||||
import org.jetbrains.anko.uiThread
|
||||
import oupson.apng.Utils.Companion.isApng
|
||||
import oupson.apng.utils.Utils.Companion.isApng
|
||||
import oupson.apng.exceptions.NotApngException
|
||||
import oupson.apng.utils.ApngAnimatorOptions
|
||||
import oupson.apng.utils.Utils
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
||||
|
@ -41,6 +44,7 @@ class ApngAnimator(private val context: Context) {
|
|||
private var doOnLoaded : (ApngAnimator) -> Unit = {}
|
||||
private var AnimationLoopListener : () -> Unit = {}
|
||||
private var duration : ArrayList<Float>? = null
|
||||
private var scaleType : ImageView.ScaleType? = null
|
||||
|
||||
var isApng = false
|
||||
var loadNotApng = true
|
||||
|
@ -74,7 +78,7 @@ class ApngAnimator(private val context: Context) {
|
|||
* @param speed The speed
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(file: File, speed: Float? = null) {
|
||||
fun load(file: File, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) {
|
||||
doAsync {
|
||||
val bytes = file.readBytes()
|
||||
if (isApng(bytes)) {
|
||||
|
@ -84,10 +88,12 @@ class ApngAnimator(private val context: Context) {
|
|||
APNGDisassembler.disassemble(file.readBytes()).frames.apply {
|
||||
draw(this)
|
||||
}
|
||||
scaleType = apngAnimatorOptions?.scaleType
|
||||
setupAnimationDrawableAndStart()
|
||||
} else {
|
||||
if (loadNotApng) {
|
||||
context.runOnUiThread {
|
||||
imageView?.scaleType = this@ApngAnimator.scaleType ?: ImageView.ScaleType.FIT_CENTER
|
||||
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
|
||||
}
|
||||
} else {
|
||||
|
@ -103,7 +109,7 @@ class ApngAnimator(private val context: Context) {
|
|||
* @param speed The speed
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(uri : Uri, speed: Float? = null) {
|
||||
fun load(uri : Uri, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) {
|
||||
doAsync {
|
||||
val bytes = context.contentResolver.openInputStream(uri).readBytes()
|
||||
if (isApng(bytes)) {
|
||||
|
@ -113,10 +119,12 @@ class ApngAnimator(private val context: Context) {
|
|||
APNGDisassembler.disassemble(bytes).frames.apply {
|
||||
draw(this)
|
||||
}
|
||||
scaleType = apngAnimatorOptions?.scaleType
|
||||
setupAnimationDrawableAndStart()
|
||||
} else {
|
||||
if (loadNotApng) {
|
||||
context.runOnUiThread {
|
||||
imageView?.scaleType = this@ApngAnimator.scaleType ?: ImageView.ScaleType.FIT_CENTER
|
||||
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
|
||||
}
|
||||
} else {
|
||||
|
@ -132,7 +140,7 @@ class ApngAnimator(private val context: Context) {
|
|||
* @param speed The speed
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun loadUrl(url: URL, speed: Float? = null) {
|
||||
fun loadUrl(url: URL, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) {
|
||||
doAsync(exceptionHandler = { e -> e.printStackTrace() }) {
|
||||
this@ApngAnimator.speed = speed
|
||||
// Download PNG
|
||||
|
@ -142,10 +150,12 @@ class ApngAnimator(private val context: Context) {
|
|||
APNGDisassembler.disassemble(this).frames.apply {
|
||||
draw(this)
|
||||
}
|
||||
scaleType = apngAnimatorOptions?.scaleType
|
||||
setupAnimationDrawableAndStart()
|
||||
} else {
|
||||
if (loadNotApng) {
|
||||
context.runOnUiThread {
|
||||
imageView?.scaleType = this@ApngAnimator.scaleType ?: ImageView.ScaleType.FIT_CENTER
|
||||
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(this@apply, 0, this@apply.size))
|
||||
}
|
||||
} else {
|
||||
|
@ -165,7 +175,7 @@ class ApngAnimator(private val context: Context) {
|
|||
* @param speed The speed
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(byteArray: ByteArray, speed: Float? = null) {
|
||||
fun load(byteArray: ByteArray, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions?) {
|
||||
doAsync {
|
||||
this@ApngAnimator.speed = speed
|
||||
if (isApng(byteArray)) {
|
||||
|
@ -173,10 +183,12 @@ class ApngAnimator(private val context: Context) {
|
|||
APNGDisassembler.disassemble(byteArray).frames.apply {
|
||||
draw(this)
|
||||
}
|
||||
scaleType = apngAnimatorOptions?.scaleType
|
||||
setupAnimationDrawableAndStart()
|
||||
} else {
|
||||
if (loadNotApng) {
|
||||
context.runOnUiThread {
|
||||
imageView?.scaleType = this@ApngAnimator.scaleType ?: ImageView.ScaleType.FIT_CENTER
|
||||
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size))
|
||||
}
|
||||
} else {
|
||||
|
@ -192,18 +204,18 @@ class ApngAnimator(private val context: Context) {
|
|||
* @param speed The speed
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(string: String, speed : Float? = null) {
|
||||
fun load(string: String, speed : Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) {
|
||||
doAsync {
|
||||
this@ApngAnimator.speed = speed
|
||||
if (string.contains("http") || string.contains("https")) {
|
||||
val url = URL(string)
|
||||
loadUrl(url, speed)
|
||||
loadUrl(url, speed, apngAnimatorOptions)
|
||||
} else if (File(string).exists()) {
|
||||
var pathToLoad = if (string.startsWith("content://")) string else "file://$string"
|
||||
pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23")
|
||||
val bytes = context.contentResolver.openInputStream(Uri.parse(pathToLoad)).readBytes()
|
||||
if (isApng(bytes)) {
|
||||
load(bytes, speed)
|
||||
load(bytes, speed, apngAnimatorOptions)
|
||||
} else {
|
||||
if (loadNotApng) {
|
||||
context.runOnUiThread {
|
||||
|
@ -226,10 +238,12 @@ class ApngAnimator(private val context: Context) {
|
|||
activeAnimation = anim
|
||||
uiThread {
|
||||
imageView?.apply {
|
||||
scaleType = this@ApngAnimator.scaleType ?: ImageView.ScaleType.FIT_CENTER
|
||||
setImageBitmap(generatedFrame[0])
|
||||
setImageDrawable(activeAnimation)
|
||||
}
|
||||
activeAnimation?.start()
|
||||
isPlaying = true
|
||||
doOnLoaded(this@ApngAnimator)
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +357,20 @@ class ApngAnimator(private val context: Context) {
|
|||
doOnLoaded = f
|
||||
}
|
||||
|
||||
fun centerCrop(boolean: Boolean) {
|
||||
if (isApng) {
|
||||
if (boolean) {
|
||||
imageView?.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
pause()
|
||||
play()
|
||||
} else {
|
||||
imageView?.scaleType = null
|
||||
pause()
|
||||
play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the generated frames into an animation drawable ([CustomAnimationDrawable])
|
||||
* in the APNG will be used instead.
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package oupson.apng
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import oupson.apng.Utils.Companion.isPng
|
||||
import oupson.apng.Utils.Companion.toByteArray
|
||||
import oupson.apng.utils.Utils.Companion.isPng
|
||||
import oupson.apng.utils.Utils.Companion.toByteArray
|
||||
import oupson.apng.chunks.IDAT
|
||||
import oupson.apng.chunks.IHDR
|
||||
import oupson.apng.exceptions.NotPngException
|
||||
import oupson.apng.utils.Utils
|
||||
|
||||
/**
|
||||
* A frame for an animated png
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package oupson.apng.chunks
|
||||
|
||||
import oupson.apng.Utils
|
||||
import oupson.apng.Utils.Companion.getBlend_op
|
||||
import oupson.apng.Utils.Companion.getDispose_op
|
||||
import oupson.apng.utils.Utils
|
||||
import oupson.apng.utils.Utils.Companion.getBlend_op
|
||||
import oupson.apng.utils.Utils.Companion.getDispose_op
|
||||
|
||||
class fcTL(byteArray: ByteArray) {
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package oupson.apng.utils
|
||||
|
||||
import android.widget.ImageView
|
||||
|
||||
class ApngAnimatorOptions(val scaleType : ImageView.ScaleType? = ImageView.ScaleType.FIT_CENTER)
|
|
@ -1,4 +1,4 @@
|
|||
package oupson.apng
|
||||
package oupson.apng.utils
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
|
@ -69,9 +69,9 @@ class Utils {
|
|||
*/
|
||||
fun getDispose_op(int: Int) : dispose_op {
|
||||
return when(int) {
|
||||
0 -> Companion.dispose_op.APNG_DISPOSE_OP_NONE
|
||||
1 -> Companion.dispose_op.APNG_DISPOSE_OP_BACKGROUND
|
||||
2 -> Companion.dispose_op.APNG_DISPOSE_OP_PREVIOUS
|
||||
0 -> dispose_op.APNG_DISPOSE_OP_NONE
|
||||
1 -> dispose_op.APNG_DISPOSE_OP_BACKGROUND
|
||||
2 -> dispose_op.APNG_DISPOSE_OP_PREVIOUS
|
||||
else -> dispose_op.APNG_DISPOSE_OP_NONE
|
||||
}
|
||||
}
|
||||
|
@ -98,10 +98,10 @@ class Utils {
|
|||
* @param int Int of the blend_op
|
||||
* @return A blend_op
|
||||
*/
|
||||
fun getBlend_op(int : Int) : blend_op{
|
||||
fun getBlend_op(int : Int) : blend_op {
|
||||
return when(int) {
|
||||
0 -> Companion.blend_op.APNG_BLEND_OP_SOURCE
|
||||
1 -> Companion.blend_op.APNG_BLEND_OP_OVER
|
||||
0 -> blend_op.APNG_BLEND_OP_SOURCE
|
||||
1 -> blend_op.APNG_BLEND_OP_OVER
|
||||
else -> blend_op.APNG_BLEND_OP_SOURCE
|
||||
}
|
||||
}
|
|
@ -7,9 +7,11 @@ import android.support.v4.app.ActivityCompat
|
|||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import kotlinx.android.synthetic.main.activity_main2.*
|
||||
import org.jetbrains.anko.sdk27.coroutines.onClick
|
||||
import oupson.apng.ApngAnimator
|
||||
import oupson.apng.utils.ApngAnimatorOptions
|
||||
|
||||
|
||||
class Main2Activity : AppCompatActivity() {
|
||||
|
@ -40,7 +42,7 @@ class Main2Activity : AppCompatActivity() {
|
|||
fun load() {
|
||||
val animator = ApngAnimator(applicationContext).loadInto(imageView3)
|
||||
val uri = intent.data
|
||||
animator.load(uri)
|
||||
animator.load(uri, null, ApngAnimatorOptions(ImageView.ScaleType.CENTER_CROP))
|
||||
imageView3.onClick {
|
||||
try {
|
||||
if (animator.isPlaying) {
|
||||
|
|
Loading…
Reference in New Issue