Add create method
This commit is contained in:
parent
681fc1ea8d
commit
e0a170c1db
|
@ -247,7 +247,7 @@ class APNGDisassembler(val byteArray: ByteArray) {
|
|||
pngList.forEach {
|
||||
val btm = Bitmap.createBitmap(it.maxWidth, it.maxHeight, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(btm)
|
||||
canvas.drawBitmap(BitmapFactory.decodeByteArray(it.byteArray, 0, it.byteArray.size), it.x_offsets.toFloat(), it.y_offsets.toFloat(), null)
|
||||
canvas.drawBitmap(BitmapFactory.decodeByteArray(it.byteArray, 0, it.byteArray.size), it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
|
||||
generatedFrame.add(btm)
|
||||
}
|
||||
return generatedFrame
|
||||
|
|
|
@ -2,6 +2,7 @@ package oupson.apng
|
|||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Log
|
||||
import oupson.apng.Utils.Companion.convertImage
|
||||
import oupson.apng.Utils.Companion.getBlend_op
|
||||
import oupson.apng.Utils.Companion.getDispose_op
|
||||
|
@ -37,12 +38,17 @@ class Apng {
|
|||
frames.add(Frame(toByteArray(bitmap), delay))
|
||||
}
|
||||
|
||||
fun addFrames(bitmap: Bitmap, delay: Float, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) {
|
||||
frames.add(Frame(toByteArray(bitmap), delay, blend_op, dispose_op))
|
||||
}
|
||||
|
||||
fun addFrames(bitmap: Bitmap, delay: Float, xOffset : Int, yOffset : Int, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) {
|
||||
frames.add(Frame(toByteArray(bitmap), delay, xOffset, yOffset, blend_op, dispose_op))
|
||||
}
|
||||
//endregion
|
||||
|
||||
fun generateAPNGByteArray() : ByteArray {
|
||||
seq = 0
|
||||
val res = ArrayList<Byte>()
|
||||
// Add PNG signature
|
||||
res.addAll(ApngFactory.pngSignature.toList())
|
||||
|
@ -77,17 +83,23 @@ class Apng {
|
|||
fcTL.addAll(to4Bytes(frames[0].height).toList())
|
||||
|
||||
// Calculate offset
|
||||
if (frames[0].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[0].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
|
||||
if (frames[0].x_offsets == null) {
|
||||
if (frames[0].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[0].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[0].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[0].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[0].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[0].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
fcTL.addAll(to4Bytes(frames[0].x_offsets!!).toList())
|
||||
fcTL.addAll(to4Bytes(frames[0].y_offsets!!).toList())
|
||||
}
|
||||
|
||||
// Set frame delay
|
||||
|
@ -154,17 +166,22 @@ class Apng {
|
|||
fcTL.addAll(to4Bytes(frames[0].height).toList())
|
||||
|
||||
// Calculate offset
|
||||
if (frames[0].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[0].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
if (frames[0].x_offsets == null) {
|
||||
if (frames[0].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[0].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[0].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[0].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[0].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[0].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
fcTL.addAll(to4Bytes(frames[0].x_offsets!!).toList())
|
||||
fcTL.addAll(to4Bytes(frames[0].y_offsets!!).toList())
|
||||
}
|
||||
|
||||
// Set frame delay
|
||||
|
@ -202,6 +219,7 @@ class Apng {
|
|||
}
|
||||
|
||||
for (i in 1 until frames.size) {
|
||||
Log.e("Seq", seq.toString())
|
||||
// If it's the first frame
|
||||
val framesByte = ArrayList<Byte>()
|
||||
val fcTL = ArrayList<Byte>()
|
||||
|
@ -217,17 +235,22 @@ class Apng {
|
|||
fcTL.addAll(to4Bytes(frames[i].width).toList())
|
||||
fcTL.addAll(to4Bytes(frames[i].height).toList())
|
||||
|
||||
if (frames[i].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[i].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
if (frames[i].x_offsets == null) {
|
||||
if (frames[i].width < maxWitdh) {
|
||||
val xOffset = (maxWitdh / 2) - (frames[i].width / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[i].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[i].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
}
|
||||
if (frames[i].height < maxHeight) {
|
||||
val xOffset = (maxHeight / 2) - (frames[i].height / 2)
|
||||
fcTL.addAll(to4Bytes(xOffset).toList())
|
||||
} else {
|
||||
fcTL.addAll(to4Bytes(0).toList())
|
||||
fcTL.addAll(to4Bytes(frames[i].x_offsets!!).toList())
|
||||
fcTL.addAll(to4Bytes(frames[i].y_offsets!!).toList())
|
||||
}
|
||||
|
||||
// Set frame delay
|
||||
|
|
|
@ -78,11 +78,11 @@ class ApngAnimator {
|
|||
// Clear current frame rect
|
||||
// If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.
|
||||
if (it.blend_op == Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE) {
|
||||
canvas.drawRect(it.x_offsets.toFloat(), it.y_offsets.toFloat(), it.x_offsets + current.width.toFloat(), it.y_offsets + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
canvas.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + current.width.toFloat(), it.y_offsets!! + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
}
|
||||
|
||||
// Draw the bitmap
|
||||
canvas.drawBitmap(current, it.x_offsets.toFloat(), it.y_offsets.toFloat(), null)
|
||||
canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
|
||||
generatedFrame.add(btm)
|
||||
|
||||
// Don't add current frame to bitmap buffer
|
||||
|
@ -95,7 +95,7 @@ class ApngAnimator {
|
|||
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(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 {
|
||||
|
@ -148,11 +148,11 @@ class ApngAnimator {
|
|||
// Clear current frame rect
|
||||
// If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.
|
||||
if (it.blend_op == Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE) {
|
||||
canvas.drawRect(it.x_offsets.toFloat(), it.y_offsets.toFloat(), it.x_offsets + current.width.toFloat(), it.y_offsets + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
canvas.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + current.width.toFloat(), it.y_offsets!! + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
}
|
||||
|
||||
// Draw the bitmap
|
||||
canvas.drawBitmap(current, it.x_offsets.toFloat(), it.y_offsets.toFloat(), null)
|
||||
canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
|
||||
generatedFrame.add(btm)
|
||||
|
||||
// Don't add current frame to bitmap buffer
|
||||
|
@ -165,7 +165,7 @@ class ApngAnimator {
|
|||
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(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 {
|
||||
|
@ -220,11 +220,11 @@ class ApngAnimator {
|
|||
// Clear current frame rect
|
||||
// If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.
|
||||
if (it.blend_op == Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE) {
|
||||
canvas.drawRect(it.x_offsets.toFloat(), it.y_offsets.toFloat(), it.x_offsets + current.width.toFloat(), it.y_offsets + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
canvas.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + current.width.toFloat(), it.y_offsets!! + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }())
|
||||
}
|
||||
|
||||
// Draw the bitmap
|
||||
canvas.drawBitmap(current, it.x_offsets.toFloat(), it.y_offsets.toFloat(), null)
|
||||
canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
|
||||
generatedFrame.add(btm)
|
||||
|
||||
// Don't add current frame to bitmap buffer
|
||||
|
@ -237,7 +237,7 @@ class ApngAnimator {
|
|||
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(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 {
|
||||
|
|
|
@ -23,8 +23,8 @@ class Frame {
|
|||
|
||||
val delay : Float
|
||||
|
||||
val x_offsets : Int
|
||||
val y_offsets : Int
|
||||
var x_offsets : Int? = null
|
||||
var y_offsets : Int? = null
|
||||
|
||||
val maxWidth : Int
|
||||
val maxHeight : Int
|
||||
|
@ -48,9 +48,6 @@ class Frame {
|
|||
|
||||
delay = 1000f
|
||||
|
||||
x_offsets = 0
|
||||
y_offsets = 0
|
||||
|
||||
maxHeight = -1
|
||||
maxWidth = -1
|
||||
blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE
|
||||
|
@ -75,9 +72,6 @@ class Frame {
|
|||
|
||||
this.delay = delay
|
||||
|
||||
x_offsets = 0
|
||||
y_offsets = 0
|
||||
|
||||
maxHeight = -1
|
||||
maxWidth = -1
|
||||
blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE
|
||||
|
@ -87,6 +81,32 @@ class Frame {
|
|||
}
|
||||
}
|
||||
|
||||
constructor(byteArray: ByteArray, delay : Float, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) {
|
||||
if (isPng(byteArray)) {
|
||||
this.byteArray = byteArray
|
||||
// Get width and height for image
|
||||
ihdr = IHDR()
|
||||
ihdr.parseIHDR(byteArray)
|
||||
|
||||
width = ihdr.pngWidth
|
||||
height = ihdr.pngHeight
|
||||
|
||||
// Get image bytes
|
||||
idat = IDAT()
|
||||
idat.parseIDAT(byteArray)
|
||||
|
||||
this.delay = delay
|
||||
|
||||
|
||||
this.maxWidth = -1
|
||||
this.maxHeight = -1
|
||||
this.blend_op = blend_op
|
||||
this.dispose_op = dispose_op
|
||||
} else {
|
||||
throw NotPngException()
|
||||
}
|
||||
}
|
||||
|
||||
constructor(byteArray: ByteArray, delay : Float, xOffsets : Int, yOffsets : Int, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) {
|
||||
if (isPng(byteArray)) {
|
||||
this.byteArray = byteArray
|
||||
|
|
|
@ -40,9 +40,9 @@ class MainActivity : AppCompatActivity() {
|
|||
val apng = Apng()
|
||||
val file1 = File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES), "hopital.jpg")
|
||||
val file2 = File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES), "test.jpg")
|
||||
apng.addFrames(BitmapFactory.decodeByteArray(file2.readBytes(), 0, file2.readBytes().size), 2000f, Utils.Companion.blend_op.APNG_BLEND_OP_OVER, Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE)
|
||||
|
||||
apng.addFrames(BitmapFactory.decodeByteArray(file1.readBytes(), 0, file1.readBytes().size))
|
||||
apng.addFrames(BitmapFactory.decodeByteArray(file2.readBytes(), 0, file2.readBytes().size), 2000f, 0, 0, Utils.Companion.blend_op.APNG_BLEND_OP_OVER, Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE)
|
||||
apng.addFrames(BitmapFactory.decodeByteArray(file1.readBytes(), 0, file1.readBytes().size), 1000f, Utils.Companion.blend_op.APNG_BLEND_OP_OVER, Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE)
|
||||
|
||||
animator = ApngAnimator(imageView)
|
||||
animator.load(apng.generateAPNGByteArray())
|
||||
|
|
Loading…
Reference in New Issue