Fix bug when drawing first frame

This commit is contained in:
oupson 2018-10-25 14:33:59 +02:00
parent 1e4b5f0476
commit 677c60ed2b
1 changed files with 30 additions and 104 deletions

View File

@ -48,14 +48,31 @@ class ApngAnimator(val context: Context) {
fun load(file: File) {
// Download PNG
val extractedFrame = APNGDisassembler(file.readBytes()).pngList
draw(extractedFrame)
nextFrame()
}
private fun draw(extractedFrame : ArrayList<Frame>) {
// Set last frame
lastFrame = extractedFrame[0]
// Init image buffer
bitmapBuffer = BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size)
generatedFrame.add(BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size))
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) {
// Iterator
val it = Frames.get(i)
@ -79,70 +96,28 @@ class ApngAnimator(val context: Context) {
}
// 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 (it.dispose_op == Utils.Companion.dispose_op.APNG_DISPOSE_OP_BACKGROUND){
val res = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
else if (it.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(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 }())
bitmapBuffer = res
}
else {
} else {
bitmapBuffer = btm
}
}
nextFrame()
}
}
}
/**
* Load an APNG file
* @param url URL to load
* @throws NotApngException
*/
private fun loadUrl(url : URL) {
doAsync(exceptionHandler = {e -> throw e}) {
doAsync(exceptionHandler = {e -> e.printStackTrace()}) {
// Download PNG
val extractedFrame = APNGDisassembler(Loader().load(context!!, url)).pngList
// Set last frame
lastFrame = extractedFrame[0]
// Init image buffer
bitmapBuffer = BitmapFactory.decodeByteArray(lastFrame?.byteArray!!, 0, lastFrame?.byteArray!!.size)
generatedFrame.add(BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size))
Frames = extractedFrame
for (i in 1 until Frames.size) {
// Iterator
val it = Frames.get(i)
// Current bitmap for the frame
val btm = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
val canvas = Canvas(btm)
val current = BitmapFactory.decodeByteArray(it.byteArray, 0, it.byteArray.size).copy(Bitmap.Config.ARGB_8888, true)
// Write buffer to canvas
canvas.drawBitmap(bitmapBuffer, 0f, 0f, null)
// 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 }())
}
// Draw the bitmap
canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
generatedFrame.add(btm)
// Don't add current frame to bitmap buffer
if (Frames[i].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 (it.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(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 }())
bitmapBuffer = res
}
else {
bitmapBuffer = btm
}
}
val extractedFrame = APNGDisassembler(Loader().load(context, url)).pngList
draw(extractedFrame)
uiThread {
nextFrame()
}
@ -152,56 +127,7 @@ class ApngAnimator(val context: Context) {
fun load(byteArray: ByteArray) {
// Download PNG
val extractedFrame = APNGDisassembler(byteArray).pngList
// Set last frame
lastFrame = extractedFrame[0]
// Init image buffer
bitmapBuffer = BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size)
generatedFrame.add(BitmapFactory.decodeByteArray(lastFrame?.byteArray, 0, lastFrame?.byteArray!!.size))
Frames = extractedFrame
for (i in 1 until Frames.size) {
// Iterator
val it = Frames.get(i)
// Current bitmap for the frame
val btm = Bitmap.createBitmap(Frames[0].maxWidth!!, Frames[0].maxHeight!!, Bitmap.Config.ARGB_8888)
val canvas = Canvas(btm)
val current = BitmapFactory.decodeByteArray(it.byteArray, 0, it.byteArray.size).copy(Bitmap.Config.ARGB_8888, true)
// Write buffer to canvas
canvas.drawBitmap(bitmapBuffer, 0f, 0f, null)
// 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 }())
}
// Draw the bitmap
canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null)
generatedFrame.add(btm)
// Don't add current frame to bitmap buffer
if (Frames[i].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 (it.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(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 }())
bitmapBuffer = res
}
else {
bitmapBuffer = btm
}
}
draw(extractedFrame)
nextFrame()
}