Small improvements

This commit is contained in:
oupson 2018-11-17 20:16:31 +01:00
parent 8c1e155695
commit 351ee29639
3 changed files with 58 additions and 86 deletions

View File

@ -43,16 +43,19 @@ class ApngAnimator(private val context: Context) {
private var duration : ArrayList<Float>? = null private var duration : ArrayList<Float>? = null
var isApng = false var isApng = false
var loadNoApng = true var loadNotApng = true
private val sharedPreferences : SharedPreferences = context.getSharedPreferences("apngAnimator", Context.MODE_PRIVATE) private val sharedPreferences : SharedPreferences = context.getSharedPreferences("apngAnimator", Context.MODE_PRIVATE)
init { init {
loadNoApng = sharedPreferences.getBoolean("loadNoApng", true) loadNotApng = sharedPreferences.getBoolean("loadNotApng", true)
} }
fun loadNoApng(boolean: Boolean) { /**
* Specify if the library could load non apng file
*/
fun loadNotApng(boolean: Boolean) {
val editor = sharedPreferences.edit() val editor = sharedPreferences.edit()
editor.putBoolean("loadNoApng", boolean) editor.putBoolean("loadNotApng", boolean)
editor.apply() editor.apply()
} }
@ -68,6 +71,7 @@ class ApngAnimator(private val context: Context) {
/** /**
* Load an APNG file and starts playing the animation. * Load an APNG file and starts playing the animation.
* @param file The file to load * @param file The file to load
* @param speed The speed
* @throws NotApngException * @throws NotApngException
*/ */
fun load(file: File, speed: Float? = null) { fun load(file: File, speed: Float? = null) {
@ -82,30 +86,36 @@ class ApngAnimator(private val context: Context) {
} }
setupAnimationDrawableAndStart() setupAnimationDrawableAndStart()
} else { } else {
if (loadNoApng) { if (loadNotApng) {
context.runOnUiThread { context.runOnUiThread {
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size)) imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
} }
} else { } else {
throw NotApngException() throw NotApngException()
} }
} }
} }
} }
fun load(uri : Uri, speed: Float? = null) { /**
doAsync { * Load an APNG file and starts playing the animation.
val bytes = context.contentResolver.openInputStream(uri).readBytes() * @param uri The uri to load
if (isApng(bytes)) { * @param speed The speed
isApng = true * @throws NotApngException
this@ApngAnimator.speed = speed */
// Download PNG fun load(uri : Uri, speed: Float? = null) {
APNGDisassembler.disassemble(bytes).frames.apply { doAsync {
draw(this) val bytes = context.contentResolver.openInputStream(uri).readBytes()
} if (isApng(bytes)) {
setupAnimationDrawableAndStart() isApng = true
} else { this@ApngAnimator.speed = speed
if (loadNoApng) { // Download PNG
APNGDisassembler.disassemble(bytes).frames.apply {
draw(this)
}
setupAnimationDrawableAndStart()
} else {
if (loadNotApng) {
context.runOnUiThread { context.runOnUiThread {
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size)) imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
} }
@ -118,8 +128,8 @@ class ApngAnimator(private val context: Context) {
/** /**
* Load an APNG file and starts playing the animation. * Load an APNG file and starts playing the animation.
* @param context The current context.
* @param url URL to load. * @param url URL to load.
* @param speed The speed
* @throws NotApngException * @throws NotApngException
*/ */
fun loadUrl(url: URL, speed: Float? = null) { fun loadUrl(url: URL, speed: Float? = null) {
@ -134,7 +144,7 @@ class ApngAnimator(private val context: Context) {
} }
setupAnimationDrawableAndStart() setupAnimationDrawableAndStart()
} else { } else {
if (loadNoApng) { if (loadNotApng) {
context.runOnUiThread { context.runOnUiThread {
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(this@apply, 0, this@apply.size)) imageView?.setImageBitmap(BitmapFactory.decodeByteArray(this@apply, 0, this@apply.size))
} }
@ -152,6 +162,7 @@ class ApngAnimator(private val context: Context) {
/** /**
* Load an APNG file and starts playing the animation. * Load an APNG file and starts playing the animation.
* @param byteArray ByteArray of the file * @param byteArray ByteArray of the file
* @param speed The speed
* @throws NotApngException * @throws NotApngException
*/ */
fun load(byteArray: ByteArray, speed: Float? = null) { fun load(byteArray: ByteArray, speed: Float? = null) {
@ -164,7 +175,7 @@ class ApngAnimator(private val context: Context) {
} }
setupAnimationDrawableAndStart() setupAnimationDrawableAndStart()
} else { } else {
if (loadNoApng) { if (loadNotApng) {
context.runOnUiThread { context.runOnUiThread {
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)) imageView?.setImageBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size))
} }
@ -177,11 +188,8 @@ class ApngAnimator(private val context: Context) {
/** /**
* Load an APNG file * Load an APNG file
* @param context The current context.
* @param string Path of the file. * @param string Path of the file.
* @param animationListener The listener that will be invoked when there are specific animation events. * @param speed The speed
* @param frameDuration The duration to show each frame. If this is null then the duration specified
* in the APNG will be used instead.
* @throws NotApngException * @throws NotApngException
*/ */
fun load(string: String, speed : Float? = null) { fun load(string: String, speed : Float? = null) {
@ -197,7 +205,7 @@ class ApngAnimator(private val context: Context) {
if (isApng(bytes)) { if (isApng(bytes)) {
load(bytes, speed) load(bytes, speed)
} else { } else {
if (loadNoApng) { if (loadNotApng) {
context.runOnUiThread { context.runOnUiThread {
imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size)) imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
} }
@ -211,9 +219,6 @@ class ApngAnimator(private val context: Context) {
/** /**
* Sets up the animation drawable and any required listeners. The animation will automatically start. * Sets up the animation drawable and any required listeners. The animation will automatically start.
* @param animationListener The listener that will be invoked when there are specific animation events.
* @param frameDuration The duration to show each frame. If this is null then the duration specified
* in the APNG will be used instead.
*/ */
private fun setupAnimationDrawableAndStart() { private fun setupAnimationDrawableAndStart() {
doAsync { doAsync {
@ -275,6 +280,9 @@ class ApngAnimator(private val context: Context) {
} }
} }
/**
* Pause the animation
*/
fun pause() { fun pause() {
if (isApng) { if (isApng) {
isPlaying = false isPlaying = false
@ -307,6 +315,9 @@ class ApngAnimator(private val context: Context) {
} }
} }
/**
* Play the animation
*/
fun play() { fun play() {
if (isApng) { if (isApng) {
isPlaying = true isPlaying = true
@ -314,6 +325,10 @@ class ApngAnimator(private val context: Context) {
} }
} }
/**
* Set animation loop listener
* @param animationLoopListener The animation loop listener.
*/
fun setOnAnimationLoopListener(animationLoopListener : () -> Unit) { fun setOnAnimationLoopListener(animationLoopListener : () -> Unit) {
if (isApng) { if (isApng) {
AnimationLoopListener = animationLoopListener AnimationLoopListener = animationLoopListener
@ -321,6 +336,9 @@ class ApngAnimator(private val context: Context) {
} }
} }
/**
* Execute on loaded
*/
fun onLoaded(f : (ApngAnimator) -> Unit) { fun onLoaded(f : (ApngAnimator) -> Unit) {
doOnLoaded = f doOnLoaded = f
} }

View File

@ -1,13 +1,8 @@
package oupson.apngcreator package oupson.apngcreator
import android.Manifest import android.Manifest
import android.content.ContentResolver
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore
import android.support.design.widget.Snackbar
import android.support.v4.app.ActivityCompat import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
@ -15,9 +10,6 @@ import android.view.View
import kotlinx.android.synthetic.main.activity_main2.* import kotlinx.android.synthetic.main.activity_main2.*
import org.jetbrains.anko.sdk27.coroutines.onClick import org.jetbrains.anko.sdk27.coroutines.onClick
import oupson.apng.ApngAnimator import oupson.apng.ApngAnimator
import oupson.apng.Utils.Companion.isApng
import oupson.apng.exceptions.NotApngException
import java.io.File
class Main2Activity : AppCompatActivity() { class Main2Activity : AppCompatActivity() {
@ -62,43 +54,12 @@ class Main2Activity : AppCompatActivity() {
} }
} }
private fun getImageRealPath(contentResolver: ContentResolver, uri: Uri, whereClause: String?): String {
var ret = ""
// Query the uri with condition.
val cursor = contentResolver.query(uri, null, whereClause, null, null)
if (cursor != null) {
val moveToFirst = cursor.moveToFirst()
if (moveToFirst) {
// Get columns name by uri type.
var columnName = MediaStore.Images.Media.DATA
if (uri === MediaStore.Images.Media.EXTERNAL_CONTENT_URI) {
columnName = MediaStore.Images.Media.DATA
} else if (uri === MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
columnName = MediaStore.Audio.Media.DATA
} else if (uri === MediaStore.Video.Media.EXTERNAL_CONTENT_URI) {
columnName = MediaStore.Video.Media.DATA
}
// Get column index.
val imageColumnIndex = cursor.getColumnIndex(columnName)
// Get column value which is the uri related file local path.
ret = cursor.getString(imageColumnIndex)
}
}
return ret
}
override fun onRequestPermissionsResult(requestCode: Int, override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) { permissions: Array<String>, grantResults: IntArray) {
when (requestCode) { when (requestCode) {
2 -> { 2 -> {
// If request is cancelled, the result arrays are empty. // If request is cancelled, the result arrays are empty.
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the // permission was granted, yay! Do the
// contacts-related task you need to do. // contacts-related task you need to do.

View File

@ -1,19 +1,12 @@
package oupson.apngcreator package oupson.apngcreator
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.util.Log import android.util.Log
import android.widget.SeekBar import android.widget.SeekBar
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.toast
import oupson.apng.APNGDisassembler
import oupson.apng.ApngAnimator import oupson.apng.ApngAnimator
import oupson.apng.Loader
import java.io.File
import java.net.URL
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {