parent
4ad6d7ca61
commit
412f9ab660
Binary file not shown.
|
@ -3,17 +3,17 @@ package oupson.apng
|
|||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.widget.ImageView
|
||||
import org.jetbrains.anko.doAsync
|
||||
import org.jetbrains.anko.uiThread
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
||||
|
||||
/**
|
||||
* Class to play APNG
|
||||
*/
|
||||
class ApngAnimator(val context: Context) {
|
||||
var isPlaying = true
|
||||
private set(value) {field = value}
|
||||
|
@ -35,6 +35,10 @@ class ApngAnimator(val context: Context) {
|
|||
|
||||
var imageView : ImageView? = null
|
||||
|
||||
/**
|
||||
* Load into an imageview
|
||||
* @param imageView Image view selected.
|
||||
*/
|
||||
fun loadInto(imageView: ImageView) : ApngAnimator {
|
||||
this.imageView = imageView
|
||||
return this
|
||||
|
@ -52,30 +56,16 @@ class ApngAnimator(val context: Context) {
|
|||
nextFrame()
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw frames
|
||||
*/
|
||||
private fun draw(extractedFrame : ArrayList<Frame>) {
|
||||
// Set last frame
|
||||
lastFrame = extractedFrame[0]
|
||||
Frames = extractedFrame
|
||||
// Init image buffer
|
||||
bitmapBuffer = BitmapFactory.decodeByteArray(lastFrame?.byteArray!!, 0, lastFrame?.byteArray!!.size)
|
||||
generatedFrame.add(BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size))
|
||||
if (lastFrame!!.dispose_op == Utils.Companion.dispose_op.APNG_DISPOSE_OP_PREVIOUS) {
|
||||
//Do nothings
|
||||
}
|
||||
// Add current frame to bitmap buffer
|
||||
// APNG_DISPOSE_OP_BACKGROUND: the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.
|
||||
else if (lastFrame!!.dispose_op == Utils.Companion.dispose_op.APNG_DISPOSE_OP_BACKGROUND) {
|
||||
val res = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
|
||||
val can = Canvas(res)
|
||||
can.drawBitmap(BitmapFactory.decodeByteArray(lastFrame?.byteArray!!, 0, lastFrame?.byteArray!!.size), 0f, 0f, null)
|
||||
can.drawRect(lastFrame!!.x_offsets!!.toFloat(), lastFrame!!.y_offsets!!.toFloat(), lastFrame!!.x_offsets!! + lastFrame!!.width.toFloat(), lastFrame!!.y_offsets!! + lastFrame!!.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
bitmapBuffer = res
|
||||
} else {
|
||||
bitmapBuffer = BitmapFactory.decodeByteArray(lastFrame?.byteArray!!, 0, lastFrame?.byteArray!!.size)
|
||||
}
|
||||
for (i in 1 until Frames.size) {
|
||||
bitmapBuffer = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
|
||||
for (i in 0 until Frames.size) {
|
||||
// Iterator
|
||||
val it = Frames.get(i)
|
||||
val it = Frames[i]
|
||||
// Current bitmap for the frame
|
||||
val btm = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(btm)
|
||||
|
@ -100,7 +90,7 @@ class ApngAnimator(val context: Context) {
|
|||
val res = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
|
||||
val can = Canvas(res)
|
||||
can.drawBitmap(btm, 0f, 0f, null)
|
||||
can.drawRect(lastFrame!!.x_offsets!!.toFloat(), lastFrame!!.y_offsets!!.toFloat(), lastFrame!!.x_offsets!! + lastFrame!!.width.toFloat(), lastFrame!!.y_offsets!! + lastFrame!!.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
can.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + it.width.toFloat(), it.y_offsets!! + it.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
bitmapBuffer = res
|
||||
} else {
|
||||
bitmapBuffer = btm
|
||||
|
@ -108,12 +98,13 @@ class ApngAnimator(val context: Context) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an APNG file
|
||||
* @param url URL to load
|
||||
* @throws NotApngException
|
||||
*/
|
||||
private fun loadUrl(url : URL) {
|
||||
fun loadUrl(url : URL) {
|
||||
doAsync(exceptionHandler = {e -> e.printStackTrace()}) {
|
||||
// Download PNG
|
||||
val extractedFrame = APNGDisassembler(Loader().load(context, url)).pngList
|
||||
|
@ -124,6 +115,11 @@ class ApngAnimator(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an APNG file
|
||||
* @param byteArray ByteArray of the file
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(byteArray: ByteArray) {
|
||||
// Download PNG
|
||||
val extractedFrame = APNGDisassembler(byteArray).pngList
|
||||
|
@ -131,6 +127,11 @@ class ApngAnimator(val context: Context) {
|
|||
nextFrame()
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an APNG file
|
||||
* @param string Path of the file
|
||||
* @throws NotApngException
|
||||
*/
|
||||
fun load(string: String) {
|
||||
if (string.contains("http") || string.contains("https")) {
|
||||
val url = URL(string)
|
||||
|
@ -140,7 +141,7 @@ class ApngAnimator(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
fun nextFrame() {
|
||||
private fun nextFrame() {
|
||||
if (imageView != null) {
|
||||
if (counter == Frames.size) {
|
||||
counter = 0
|
||||
|
@ -171,6 +172,9 @@ class ApngAnimator(val context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return animation drawable of the APNG
|
||||
*/
|
||||
fun toAnimationDrawable() : AnimationDrawable {
|
||||
val animDrawable = AnimationDrawable()
|
||||
for (i in 0 until generatedFrame.size) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package oupson.apng
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
|
|
|
@ -47,6 +47,7 @@ dependencies {
|
|||
implementation project(":apng_library")
|
||||
// implementation fileTree(include: ['*.aar'], dir: 'libs')
|
||||
//implementation 'com.github.oupson:Kapng-Android:1.0.0'
|
||||
implementation 'com.android.support:design:27.1.1' // where X.X.X version
|
||||
}
|
||||
kotlin {
|
||||
experimental {
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package oupson.apngcreator;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class BitmapDrawable extends Drawable {
|
||||
private Bitmap mBitmap;
|
||||
|
||||
BitmapDrawable(Bitmap b) {
|
||||
mBitmap = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mBitmap.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mBitmap.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinimumWidth() {
|
||||
return mBitmap.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinimumHeight() {
|
||||
return mBitmap.getHeight();
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return mBitmap;
|
||||
}
|
||||
}
|
|
@ -1,39 +1,75 @@
|
|||
package oupson.apngcreator
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ContentResolver
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.support.design.widget.Snackbar
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.util.Log
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.activity_main2.*
|
||||
import org.jetbrains.anko.sdk27.coroutines.onClick
|
||||
import oupson.apng.ApngAnimator
|
||||
import oupson.apng.exceptions.NotApngException
|
||||
|
||||
|
||||
class Main2Activity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main2)
|
||||
|
||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val animator = ApngAnimator(this).loadInto(imageView2)
|
||||
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||
2)
|
||||
} else {
|
||||
load()
|
||||
}
|
||||
}
|
||||
|
||||
fun load() {
|
||||
val animator = ApngAnimator(this).loadInto(imageView3)
|
||||
val uri = intent.data
|
||||
if (uri.toString().contains("file:///")) {
|
||||
animator.load(uri.path)
|
||||
try {
|
||||
animator.load(uri.path)
|
||||
} catch (e : NotApngException) {
|
||||
imageView3.setImageBitmap(BitmapFactory.decodeFile(uri.path))
|
||||
Snackbar.make(constraint, "Not an APNG", Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
animator.load(getImageRealPath(contentResolver, uri, null))
|
||||
} catch (e : NotApngException) {
|
||||
imageView3.setImageBitmap(BitmapFactory.decodeFile(getImageRealPath(contentResolver, uri, null)))
|
||||
Snackbar.make(constraint, "Not an APNG", Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
Log.e("TAG", intent.data.toString())
|
||||
animator.load(getImageRealPath(contentResolver, uri, null))
|
||||
|
||||
imageView3.onClick {
|
||||
if (animator.isPlaying) {
|
||||
animator.pause()
|
||||
} else {
|
||||
animator.play()
|
||||
try {
|
||||
if (animator.isPlaying) {
|
||||
animator.pause()
|
||||
} else {
|
||||
animator.play()
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +83,6 @@ class Main2Activity : AppCompatActivity() {
|
|||
if (cursor != null) {
|
||||
val moveToFirst = cursor.moveToFirst()
|
||||
if (moveToFirst) {
|
||||
|
||||
// Get columns name by uri type.
|
||||
var columnName = MediaStore.Images.Media.DATA
|
||||
|
||||
|
@ -69,4 +104,26 @@ class Main2Activity : AppCompatActivity() {
|
|||
|
||||
return ret
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int,
|
||||
permissions: Array<String>, grantResults: IntArray) {
|
||||
when (requestCode) {
|
||||
2 -> {
|
||||
// If request is cancelled, the result arrays are empty.
|
||||
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// permission was granted, yay! Do the
|
||||
// contacts-related task you need to do.
|
||||
|
||||
load()
|
||||
|
||||
} else {
|
||||
// permission denied, boo! Disable the
|
||||
// functionality that depends on this permission.
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
}// other 'case' lines to check for other
|
||||
// permissions this app might request.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/constraint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#323232"
|
||||
tools:context=".Main2Activity">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
|
|
Loading…
Reference in New Issue