Add create method

This commit is contained in:
oupson 2018-10-23 16:48:48 +02:00
parent 681fc1ea8d
commit e0a170c1db
5 changed files with 93 additions and 50 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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())