Working on ExperimentalApngEncoder.kt
This commit is contained in:
parent
be3322a34e
commit
d8d58259e1
|
@ -23,10 +23,7 @@ class ExperimentalApngEncoder(
|
|||
private val outputStream: OutputStream,
|
||||
private val width: Int,
|
||||
private val height: Int,
|
||||
numberOfFrames: Int,
|
||||
private val encodeAlpha: Boolean = true,
|
||||
filter: Int = 0,
|
||||
compressionLevel: Int = 0
|
||||
numberOfFrames: Int
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "ExperimentalApngEncoder"
|
||||
|
@ -66,7 +63,10 @@ class ExperimentalApngEncoder(
|
|||
private var compressionLevel: Int = 0
|
||||
|
||||
/** The filter type. */
|
||||
private var filter: Int = 0
|
||||
private var filter: Int = FILTER_NONE
|
||||
|
||||
/** If the alpha channel must be encoded */
|
||||
private var encodeAlpha : Boolean = true
|
||||
|
||||
/** The prior row. */
|
||||
private var priorRow: ByteArray? = null
|
||||
|
@ -74,21 +74,72 @@ class ExperimentalApngEncoder(
|
|||
/** The left bytes. */
|
||||
private var leftBytes: ByteArray? = null
|
||||
|
||||
/** Number of loop of the animation, zero to infinite **/
|
||||
private var repetitionCount : Int = 0
|
||||
|
||||
init {
|
||||
this.filter = FILTER_NONE
|
||||
if (filter <= FILTER_LAST) {
|
||||
this.filter = filter
|
||||
}
|
||||
|
||||
if (compressionLevel in 0..9) {
|
||||
this.compressionLevel = compressionLevel
|
||||
}
|
||||
|
||||
outputStream.write(Utils.pngSignature)
|
||||
writeHeader()
|
||||
writeACTL(numberOfFrames)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the alpha channel must be encoded.
|
||||
* @param encodeAlpha If the alpha channel must be encoded.
|
||||
* @return [ExperimentalApngEncoder] for chaining.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun encodeAlpha(encodeAlpha : Boolean) : ExperimentalApngEncoder {
|
||||
this.encodeAlpha = encodeAlpha
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter.
|
||||
* @param filter The filter.
|
||||
* Values :
|
||||
* - [FILTER_NONE]
|
||||
* - [FILTER_SUB]
|
||||
* - [FILTER_UP]
|
||||
* - [FILTER_LAST]
|
||||
* @return [ExperimentalApngEncoder] for chaining.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun filter(filter : Int) : ExperimentalApngEncoder {
|
||||
if (filter <= FILTER_LAST) {
|
||||
this.filter = filter
|
||||
} else {
|
||||
Log.e(TAG, "Invalid filter")
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the repetition count.
|
||||
* @param repetitionCount The number of repetition, zero for infinite.
|
||||
* @return [ExperimentalApngEncoder] for chaining.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun repetitionCount(repetitionCount : Int) : ExperimentalApngEncoder{
|
||||
this.repetitionCount = repetitionCount
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compression level
|
||||
* @param compressionLevel A integer between 0 and 9 (not include)
|
||||
* @return [ExperimentalApngEncoder] for chaining
|
||||
*/
|
||||
fun compressionLevel(compressionLevel : Int) : ExperimentalApngEncoder {
|
||||
if (compressionLevel in 0..9) {
|
||||
this.compressionLevel = compressionLevel
|
||||
} else {
|
||||
Log.e(TAG, "Invalid compression level : $compressionLevel, expected a number in range 0..9")
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun writeFrame(
|
||||
inputStream: InputStream,
|
||||
|
@ -120,7 +171,11 @@ class ExperimentalApngEncoder(
|
|||
throw Exception("Height of first frame must be equal to height of APNG. (${btm.height} != $height)")
|
||||
}
|
||||
|
||||
// TODO CHECK IF btm IS BIGGER THANT THE APNG
|
||||
// TODO PROPER EXCEPTION
|
||||
if (btm.width > width)
|
||||
throw Exception("Frame width must be inferior or equal at the animation width")
|
||||
else if (btm.height > height)
|
||||
throw Exception("Frame height must be inferior or equal at the animation height")
|
||||
|
||||
writeFCTL(btm, delay, disposeOp, blendOp, xOffsets, yOffsets)
|
||||
writeImageData(btm)
|
||||
|
@ -193,7 +248,7 @@ class ExperimentalApngEncoder(
|
|||
actl.addAll(Utils.to4Bytes(num).asList())
|
||||
|
||||
// Number of repeat, 0 to infinite
|
||||
actl.addAll(Utils.to4Bytes(0).asList())
|
||||
actl.addAll(Utils.to4Bytes(repetitionCount).asList())
|
||||
outputStream.write(actl.toByteArray())
|
||||
|
||||
// generate crc
|
||||
|
|
|
@ -122,7 +122,12 @@ class CreatorActivity : AppCompatActivity() {
|
|||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||
|
||||
val encoder = ExperimentalApngEncoder(out, maxWidth, maxHeight, items.size, compressionLevel = 9)
|
||||
val encoder = ExperimentalApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
items.forEachIndexed { i, uri ->
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(TAG, "Encoding frame $i")
|
||||
|
@ -164,7 +169,7 @@ class CreatorActivity : AppCompatActivity() {
|
|||
out.close()
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(TAG, "${f.length() / 1000}ko")
|
||||
Log.v(TAG, "Animation size is ${f.length() / 1000}ko")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
|
@ -202,7 +207,12 @@ class CreatorActivity : AppCompatActivity() {
|
|||
str?.close()
|
||||
}
|
||||
|
||||
val encoder = ExperimentalApngEncoder(out, maxWidth, maxHeight, items.size, compressionLevel = 9)
|
||||
val encoder = ExperimentalApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
items.forEach { uri ->
|
||||
println("delay : ${uri.second.toFloat()}ms")
|
||||
val str = contentResolver.openInputStream(uri.first) ?: return@forEach
|
||||
|
@ -317,7 +327,12 @@ class CreatorActivity : AppCompatActivity() {
|
|||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||
|
||||
val encoder = ExperimentalApngEncoder(out, maxWidth, maxHeight, items.size, compressionLevel = 9)
|
||||
val encoder = ExperimentalApngEncoder(
|
||||
out,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
items.size
|
||||
).compressionLevel(9)
|
||||
items.forEach { uri ->
|
||||
// println("delay : ${adapter?.delay?.get(i)?.toFloat() ?: 1000f}ms")
|
||||
val str =
|
||||
|
|
Loading…
Reference in New Issue