Adding support for first frame not in animation

Fixing a bug
This commit is contained in:
Oupson 2020-09-23 21:09:58 +02:00
parent 39fdc31aaa
commit dfc427a54f
4 changed files with 52 additions and 20 deletions

View File

@ -15,7 +15,6 @@ import java.util.zip.DeflaterOutputStream
import kotlin.math.max
import kotlin.math.min
// TODO ADD SUPPORT FOR FIRST FRAME NOT IN ANIM
// TODO OPTIMISE APNG
/**
* A class to write APNG.
@ -90,6 +89,9 @@ class ExperimentalApngEncoder(
/** Number of loop of the animation, zero to infinite **/
private var repetitionCount: Int = 0
/** If the first frame should be included in the animation **/
private var firstFrameInAnim: Boolean = true
init {
outputStream.write(Utils.pngSignature)
writeHeader()
@ -139,9 +141,9 @@ class ExperimentalApngEncoder(
}
/**
* Set the compression level
* @param compressionLevel A integer between 0 and 9 (not include)
* @return [ExperimentalApngEncoder] for chaining
* 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) {
@ -156,6 +158,16 @@ class ExperimentalApngEncoder(
return this
}
/**
* Set if the first frame should be included in the animation.
* @param firstFrameInAnim A boolean.
* @return [ExperimentalApngEncoder] for chaining.
*/
fun firstFrameInAnim(firstFrameInAnim: Boolean): ExperimentalApngEncoder {
this.firstFrameInAnim = firstFrameInAnim
return this
}
/**
* Write a frame into the output stream.
* @param inputStream An input stream that will be decoded in order to be written in the animation. Not freed.
@ -221,9 +233,10 @@ class ExperimentalApngEncoder(
else if (btm.height > height)
throw InvalidFrameSizeException("Frame height must be inferior or equal at the animation height")
if (firstFrameInAnim || currentFrame != 0)
writeFCTL(btm, delay, disposeOp, blendOp, xOffsets, yOffsets)
writeImageData(btm)
currentSeq++
currentFrame++
}
/**

View File

@ -39,6 +39,7 @@ class CreatorActivity : AppCompatActivity() {
private var items: ArrayList<Pair<Uri, Int>> = ArrayList()
private var adapter: ImageAdapter? = null
private var firstFrameInAnim = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -84,6 +85,7 @@ class CreatorActivity : AppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.creator_menu, menu)
menu?.findItem(R.id.menu_first_frame_in_anim)?.isChecked = true
return true
}
@ -128,6 +130,7 @@ class CreatorActivity : AppCompatActivity() {
maxHeight,
items.size
).compressionLevel(9)
.firstFrameInAnim(firstFrameInAnim)
items.forEachIndexed { i, uri ->
if (BuildConfig.DEBUG)
Log.v(TAG, "Encoding frame $i")
@ -213,6 +216,8 @@ class CreatorActivity : AppCompatActivity() {
maxHeight,
items.size
).compressionLevel(9)
.firstFrameInAnim(firstFrameInAnim)
items.forEach { uri ->
println("delay : ${uri.second.toFloat()}ms")
val str = contentResolver.openInputStream(uri.first) ?: return@forEach
@ -236,6 +241,7 @@ class CreatorActivity : AppCompatActivity() {
)
)
type = "image/png"
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(
Intent.createChooser(
@ -285,6 +291,11 @@ class CreatorActivity : AppCompatActivity() {
adapter?.notifyDataSetChanged()
true
}
R.id.menu_first_frame_in_anim -> {
item.isChecked = !item.isChecked
firstFrameInAnim = item.isChecked
true
}
else -> if (item != null) super.onOptionsItemSelected(item) else true
}
}
@ -333,6 +344,8 @@ class CreatorActivity : AppCompatActivity() {
maxHeight,
items.size
).compressionLevel(9)
.firstFrameInAnim(firstFrameInAnim)
items.forEach { uri ->
// println("delay : ${adapter?.delay?.get(i)?.toFloat() ?: 1000f}ms")
val str =

View File

@ -1,38 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_save_apng"
android:icon="@drawable/ic_save_white_24dp"
android:title="@string/save"
app:showAsAction="ifRoom"
app:iconTint="@color/control"/>
app:iconTint="@color/control"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_create_apng"
android:icon="@drawable/ic_play_arrow_white_24dp"
android:title="@string/create"
app:showAsAction="ifRoom"
app:iconTint="@color/control"/>
app:iconTint="@color/control"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_share_apng"
android:icon="@drawable/ic_share_share_24dp"
android:title="@string/share"
app:showAsAction="ifRoom"
app:iconTint="@color/control"/>
app:iconTint="@color/control"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_set_all_duration"
android:icon="@drawable/ic_access_time_white_24dp"
android:title="@string/set_all_duration"
app:showAsAction="ifRoom"
app:iconTint="@color/control"/>
app:iconTint="@color/control"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_clear"
android:title="@string/clear"
app:showAsAction="never"
app:iconTint="@color/control" />
app:iconTint="@color/control"
app:showAsAction="never" />
<item
android:id="@+id/menu_first_frame_in_anim"
android:checkable="true"
android:title="@string/menu_first_frame_in_anim"
app:showAsAction="never|withText" />
</menu>

View File

@ -16,6 +16,7 @@
<string name="set_all_duration">Set duration of all frames</string>
<string name="done">Done</string>
<string name="clear">Clear</string>
<string name="menu_first_frame_in_anim">First frame in animation</string>
<string name="open">open</string>
<string name="close">close</string>