Fixing a bug on ApngEncoder.kt
Working on CreatorActivity.kt
This commit is contained in:
parent
4e807e8b06
commit
6eff6f0f45
|
@ -374,7 +374,7 @@ class ApngEncoder(
|
|||
* @return [Boolean] true if no errors; false if error grabbing pixels
|
||||
*/
|
||||
private fun writeImageData(image: Bitmap): Boolean {
|
||||
var rowsLeft = height // number of rows remaining to write
|
||||
var rowsLeft = image.height // number of rows remaining to write
|
||||
var startRow = 0 // starting row to process this time through
|
||||
var nRows: Int // how many rows to grab at a time
|
||||
|
||||
|
@ -395,31 +395,31 @@ class ApngEncoder(
|
|||
val compBytes = DeflaterOutputStream(outBytes, scrunch)
|
||||
try {
|
||||
while (rowsLeft > 0) {
|
||||
nRows = min(32767 / (width * (bytesPerPixel + 1)), rowsLeft)
|
||||
nRows = min(32767 / ( image.width * (bytesPerPixel + 1)), rowsLeft)
|
||||
nRows = max(nRows, 1)
|
||||
|
||||
val pixels = IntArray(width * nRows)
|
||||
val pixels = IntArray( image.width * nRows)
|
||||
|
||||
//pg = new PixelGrabber(image, 0, startRow, width, nRows, pixels, 0, width);
|
||||
image.getPixels(pixels, 0, width, 0, startRow, width, nRows)
|
||||
image.getPixels(pixels, 0, image.width, 0, startRow, image.width, nRows)
|
||||
|
||||
/*
|
||||
* Create a data chunk. scanLines adds "nRows" for
|
||||
* the filter bytes.
|
||||
*/
|
||||
scanLines = ByteArray(width * nRows * bytesPerPixel + nRows)
|
||||
scanLines = ByteArray( image.width * nRows * bytesPerPixel + nRows)
|
||||
|
||||
if (filter == FILTER_SUB) {
|
||||
leftBytes = ByteArray(16)
|
||||
}
|
||||
if (filter == FILTER_UP) {
|
||||
priorRow = ByteArray(width * bytesPerPixel)
|
||||
priorRow = ByteArray( image.width * bytesPerPixel)
|
||||
}
|
||||
|
||||
scanPos = 0
|
||||
startPos = 1
|
||||
for (i in 0 until width * nRows) {
|
||||
if (i % width == 0) {
|
||||
for (i in 0 until image.width * nRows) {
|
||||
if (i % image.width == 0) {
|
||||
scanLines[scanPos++] = filter.toByte()
|
||||
startPos = scanPos
|
||||
}
|
||||
|
@ -429,12 +429,12 @@ class ApngEncoder(
|
|||
if (encodeAlpha) {
|
||||
scanLines[scanPos++] = (pixels[i] shr 24 and 0xff).toByte()
|
||||
}
|
||||
if (i % width == width - 1 && filter != FILTER_NONE) {
|
||||
if (i % image.width == image.width - 1 && filter != FILTER_NONE) {
|
||||
if (filter == FILTER_SUB) {
|
||||
filterSub(scanLines, startPos, width)
|
||||
filterSub(scanLines, startPos, image.width)
|
||||
}
|
||||
if (filter == FILTER_UP) {
|
||||
filterUp(scanLines, startPos, width)
|
||||
filterUp(scanLines, startPos, image.width)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import oupson.apngcreator.adapter.ImageAdapter
|
|||
import oupson.apngcreator.dialogs.DelayInputDialog
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
||||
class CreatorActivity : AppCompatActivity() {
|
||||
|
@ -101,74 +102,7 @@ class CreatorActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
val out = FileOutputStream(f)
|
||||
var maxWidth = 0
|
||||
var maxHeight = 0
|
||||
items.forEach {
|
||||
val str = contentResolver.openInputStream(it.first)
|
||||
if (str == null) {
|
||||
Log.e(TAG, "Input Stream is null : ${it.first}")
|
||||
return@forEach
|
||||
}
|
||||
val btm = BitmapFactory.decodeStream(str)
|
||||
if (btm != null) {
|
||||
if (btm.width > maxWidth)
|
||||
maxWidth = btm.width
|
||||
if (btm.height > maxHeight)
|
||||
maxHeight = btm.height
|
||||
} else {
|
||||
Log.e(TAG, "Btm is null")
|
||||
}
|
||||
str.close()
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||
|
||||
val encoder = ApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
.firstFrameInAnim(firstFrameInAnim)
|
||||
items.forEachIndexed { i, uri ->
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(TAG, "Encoding frame $i")
|
||||
// println("delay : ${adapter?.delay?.get(i)?.toFloat() ?: 1000f}ms")
|
||||
try {
|
||||
val str = contentResolver.openInputStream(uri.first)
|
||||
?: return@forEachIndexed
|
||||
if (i == 0) {
|
||||
val btm =
|
||||
BitmapFactory.decodeStream(str) ?: return@forEachIndexed
|
||||
str.close()
|
||||
encoder.writeFrame(
|
||||
if (btm.width != maxWidth && btm.height != maxHeight)
|
||||
Bitmap.createScaledBitmap(
|
||||
btm,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
false
|
||||
)
|
||||
else
|
||||
btm,
|
||||
delay = uri.second.toFloat(),
|
||||
disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE
|
||||
)
|
||||
//input.close()
|
||||
} else {
|
||||
encoder.writeFrame(
|
||||
str,
|
||||
delay = uri.second.toFloat(),
|
||||
)
|
||||
}
|
||||
str.close()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error when creating apng", e)
|
||||
}
|
||||
}
|
||||
|
||||
encoder.writeEnd()
|
||||
saveToOutputStream(out)
|
||||
out.close()
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
|
@ -198,36 +132,7 @@ class CreatorActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
val out = FileOutputStream(f)
|
||||
var maxWidth = 0
|
||||
var maxHeight = 0
|
||||
items.forEach {
|
||||
val str = contentResolver.openInputStream(it.first)
|
||||
val btm = BitmapFactory.decodeStream(str)
|
||||
if (btm.width > maxWidth)
|
||||
maxWidth = btm.width
|
||||
if (btm.height > maxHeight)
|
||||
maxHeight = btm.height
|
||||
str?.close()
|
||||
}
|
||||
|
||||
val encoder = ApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
.firstFrameInAnim(firstFrameInAnim)
|
||||
|
||||
items.forEach { uri ->
|
||||
println("delay : ${uri.second.toFloat()}ms")
|
||||
val str = contentResolver.openInputStream(uri.first) ?: return@forEach
|
||||
encoder.writeFrame(
|
||||
str,
|
||||
delay = uri.second.toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
encoder.writeEnd()
|
||||
saveToOutputStream(out)
|
||||
out.close()
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
|
@ -300,6 +205,78 @@ class CreatorActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun saveToOutputStream(outputStream: OutputStream) {
|
||||
var maxWidth = 0
|
||||
var maxHeight = 0
|
||||
items.forEach {
|
||||
val str = contentResolver.openInputStream(it.first)
|
||||
if (str == null) {
|
||||
Log.e(TAG, "Input Stream is null : ${it.first}")
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val btm = BitmapFactory.decodeStream(str)
|
||||
if (btm != null) {
|
||||
if (btm.width > maxWidth)
|
||||
maxWidth = btm.width
|
||||
if (btm.height > maxHeight)
|
||||
maxHeight = btm.height
|
||||
} else {
|
||||
Log.e(TAG, "Btm is null")
|
||||
}
|
||||
str.close()
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||
|
||||
val encoder = ApngEncoder(
|
||||
outputStream,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
.firstFrameInAnim(firstFrameInAnim)
|
||||
|
||||
items.forEachIndexed { i, uri ->
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(TAG, "Encoding frame $i")
|
||||
|
||||
try {
|
||||
val str = contentResolver.openInputStream(uri.first)
|
||||
?: return@forEachIndexed
|
||||
if (i == 0) {
|
||||
val btm =
|
||||
BitmapFactory.decodeStream(str) ?: return@forEachIndexed
|
||||
str.close()
|
||||
encoder.writeFrame(
|
||||
if (btm.width != maxWidth && btm.height != maxHeight)
|
||||
Bitmap.createScaledBitmap(
|
||||
btm,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
false
|
||||
)
|
||||
else
|
||||
btm,
|
||||
delay = uri.second.toFloat(),
|
||||
disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE
|
||||
)
|
||||
} else {
|
||||
encoder.writeFrame(
|
||||
str,
|
||||
delay = uri.second.toFloat(),
|
||||
)
|
||||
}
|
||||
str.close()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error when creating apng", e)
|
||||
}
|
||||
}
|
||||
|
||||
encoder.writeEnd()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
|
@ -321,42 +298,10 @@ class CreatorActivity : AppCompatActivity() {
|
|||
if (data?.data != null) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "Intent data : ${data.data}")
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val out = contentResolver.openOutputStream(data.data!!) ?: return@launch
|
||||
var maxWidth = 0
|
||||
var maxHeight = 0
|
||||
items.forEach {
|
||||
val str = contentResolver.openInputStream(it.first)
|
||||
val btm = BitmapFactory.decodeStream(str)
|
||||
if (btm.width > maxWidth)
|
||||
maxWidth = btm.width
|
||||
if (btm.height > maxHeight)
|
||||
maxHeight = btm.height
|
||||
str?.close()
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||
|
||||
val encoder = ApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
.firstFrameInAnim(firstFrameInAnim)
|
||||
|
||||
items.forEach { uri ->
|
||||
// println("delay : ${adapter?.delay?.get(i)?.toFloat() ?: 1000f}ms")
|
||||
val str =
|
||||
contentResolver.openInputStream(uri.first) ?: return@forEach
|
||||
encoder.writeFrame(
|
||||
str,
|
||||
delay = uri.second.toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
encoder.writeEnd()
|
||||
saveToOutputStream(out)
|
||||
out.close()
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
Loading…
Reference in New Issue