Working on application
This commit is contained in:
parent
e7b368a013
commit
dc4f77d6c8
|
@ -9,7 +9,7 @@
|
||||||
<application
|
<application
|
||||||
android:fullBackupContent="false"
|
android:fullBackupContent="false"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:hardwareAccelerated="false"
|
android:hardwareAccelerated="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
|
@ -44,6 +45,7 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
private var items: ArrayList<Triple<Uri, Int, Long>> = ArrayList()
|
private var items: ArrayList<Triple<Uri, Int, Long>> = ArrayList()
|
||||||
private var adapter: ImageAdapter? = null
|
private var adapter: ImageAdapter? = null
|
||||||
private var firstFrameInAnim = true
|
private var firstFrameInAnim = true
|
||||||
|
private var optimise = true
|
||||||
|
|
||||||
private var nextImageId : Long= 0
|
private var nextImageId : Long= 0
|
||||||
|
|
||||||
|
@ -81,7 +83,11 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
DelayInputDialog(object : DelayInputDialog.InputSenderDialogListener {
|
DelayInputDialog(object : DelayInputDialog.InputSenderDialogListener {
|
||||||
override fun onOK(number: Int?) {
|
override fun onOK(number: Int?) {
|
||||||
if (number != null) {
|
if (number != null) {
|
||||||
items[position] = Triple(items[position].first, number, items[position].third)
|
items[position] = Triple(
|
||||||
|
items[position].first,
|
||||||
|
number,
|
||||||
|
items[position].third
|
||||||
|
)
|
||||||
adapter?.notifyDataSetChanged()
|
adapter?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +104,7 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.creator_menu, menu)
|
menuInflater.inflate(R.menu.creator_menu, menu)
|
||||||
menu?.findItem(R.id.menu_first_frame_in_anim)?.isChecked = true
|
menu?.findItem(R.id.menu_first_frame_in_anim)?.isChecked = true
|
||||||
|
menu?.findItem(R.id.menu_optimise)?.isChecked = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +125,18 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
Log.v(TAG, "Animation size is ${f.length() / 1000}ko")
|
Log.v(TAG, "File size is ${f.length() / 1000}kB")
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast
|
||||||
|
.makeText(
|
||||||
|
this@CreatorActivity, getString(
|
||||||
|
R.string.file_size_kB,
|
||||||
|
f.length() / 1000
|
||||||
|
), Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
intent.data = FileProvider.getUriForFile(
|
intent.data = FileProvider.getUriForFile(
|
||||||
this@CreatorActivity,
|
this@CreatorActivity,
|
||||||
|
@ -149,6 +165,15 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast
|
||||||
|
.makeText(
|
||||||
|
this@CreatorActivity, getString(
|
||||||
|
R.string.file_size_kB,
|
||||||
|
f.length() / 1000
|
||||||
|
), Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
|
|
||||||
val intent = Intent().apply {
|
val intent = Intent().apply {
|
||||||
action = Intent.ACTION_SEND
|
action = Intent.ACTION_SEND
|
||||||
val uri = FileProvider.getUriForFile(
|
val uri = FileProvider.getUriForFile(
|
||||||
|
@ -160,7 +185,11 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
Intent.EXTRA_STREAM, uri
|
Intent.EXTRA_STREAM, uri
|
||||||
)
|
)
|
||||||
|
|
||||||
clipData = ClipData.newUri(contentResolver, getString(R.string.share), uri)
|
clipData = ClipData.newUri(
|
||||||
|
contentResolver,
|
||||||
|
getString(R.string.share),
|
||||||
|
uri
|
||||||
|
)
|
||||||
type = "image/png"
|
type = "image/png"
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
}
|
}
|
||||||
|
@ -217,6 +246,11 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
firstFrameInAnim = item.isChecked
|
firstFrameInAnim = item.isChecked
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.menu_optimise -> {
|
||||||
|
item.isChecked = !item.isChecked
|
||||||
|
optimise = item.isChecked
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> if (item != null) super.onOptionsItemSelected(item) else true
|
else -> if (item != null) super.onOptionsItemSelected(item) else true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,20 +265,19 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
val btm = BitmapFactory.decodeStream(str)
|
val options = BitmapFactory.Options()
|
||||||
if (btm != null) {
|
options.inJustDecodeBounds = true
|
||||||
if (btm.width > maxWidth)
|
|
||||||
maxWidth = btm.width
|
BitmapFactory.decodeStream(str, null, options)
|
||||||
if (btm.height > maxHeight)
|
if (options.outWidth > maxWidth)
|
||||||
maxHeight = btm.height
|
maxWidth = options.outWidth
|
||||||
} else {
|
if (options.outHeight > maxHeight)
|
||||||
Log.e(TAG, "Btm is null")
|
maxHeight = options.outHeight
|
||||||
}
|
|
||||||
str.close()
|
str.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
Log.i(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
Log.d(TAG, "MaxWidth : $maxWidth; MaxHeight : $maxHeight")
|
||||||
|
|
||||||
val encoder = ApngEncoder(
|
val encoder = ApngEncoder(
|
||||||
outputStream,
|
outputStream,
|
||||||
|
@ -253,6 +286,7 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
items.size
|
items.size
|
||||||
).setCompressionLevel(9)
|
).setCompressionLevel(9)
|
||||||
.setIsFirstFrameInAnim(firstFrameInAnim)
|
.setIsFirstFrameInAnim(firstFrameInAnim)
|
||||||
|
.setOptimiseApng(optimise)
|
||||||
|
|
||||||
items.forEachIndexed { i, uri ->
|
items.forEachIndexed { i, uri ->
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
|
@ -263,21 +297,22 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
?: return@forEachIndexed
|
?: return@forEachIndexed
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
val btm =
|
val btm =
|
||||||
BitmapFactory.decodeStream(str) ?: return@forEachIndexed
|
BitmapFactory.decodeStream(str)
|
||||||
str.close()
|
if (btm != null) {
|
||||||
encoder.writeFrame(
|
encoder.writeFrame(
|
||||||
if (btm.width != maxWidth && btm.height != maxHeight)
|
if (btm.width != maxWidth && btm.height != maxHeight)
|
||||||
Bitmap.createScaledBitmap(
|
Bitmap.createScaledBitmap(
|
||||||
|
btm,
|
||||||
|
maxWidth,
|
||||||
|
maxHeight,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
else
|
||||||
btm,
|
btm,
|
||||||
maxWidth,
|
delay = uri.second.toFloat(),
|
||||||
maxHeight,
|
disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE
|
||||||
false
|
)
|
||||||
)
|
}
|
||||||
else
|
|
||||||
btm,
|
|
||||||
delay = uri.second.toFloat(),
|
|
||||||
disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
encoder.writeFrame(
|
encoder.writeFrame(
|
||||||
str,
|
str,
|
||||||
|
@ -343,7 +378,10 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class SwipeToDeleteCallback(private val adapter: ImageAdapter) :
|
inner class SwipeToDeleteCallback(private val adapter: ImageAdapter) :
|
||||||
ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
ItemTouchHelper.SimpleCallback(
|
||||||
|
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
|
||||||
|
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
|
||||||
|
) {
|
||||||
override fun onMove(
|
override fun onMove(
|
||||||
recyclerView: RecyclerView,
|
recyclerView: RecyclerView,
|
||||||
viewHolder: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
|
|
@ -11,7 +11,6 @@ import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import kotlinx.android.synthetic.main.activity_viewer.*
|
import kotlinx.android.synthetic.main.activity_viewer.*
|
||||||
import oupson.apng.decoder.ApngDecoder
|
import oupson.apng.decoder.ApngDecoder
|
||||||
import oupson.apngcreator.BuildConfig
|
|
||||||
import oupson.apngcreator.R
|
import oupson.apngcreator.R
|
||||||
|
|
||||||
class ViewerActivity : AppCompatActivity() {
|
class ViewerActivity : AppCompatActivity() {
|
||||||
|
@ -44,8 +43,7 @@ class ViewerActivity : AppCompatActivity() {
|
||||||
ApngDecoder.decodeApngAsyncInto(this, uri, viewerImageView, callback = object : ApngDecoder.Callback {
|
ApngDecoder.decodeApngAsyncInto(this, uri, viewerImageView, callback = object : ApngDecoder.Callback {
|
||||||
override fun onSuccess(drawable: Drawable) {}
|
override fun onSuccess(drawable: Drawable) {}
|
||||||
override fun onError(error: Exception) {
|
override fun onError(error: Exception) {
|
||||||
if (BuildConfig.DEBUG)
|
Log.e("ViewerActivity", "Error when loading file", error)
|
||||||
Log.e("ViewerActivity", "Error when loading file", error)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,7 @@ class ApngDecoderFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
override fun onError(error: Exception) {
|
||||||
if (BuildConfig.DEBUG)
|
Log.e(TAG, "onError : $error")
|
||||||
Log.e(TAG, "onError : $error")
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,4 +40,9 @@
|
||||||
android:checkable="true"
|
android:checkable="true"
|
||||||
android:title="@string/menu_first_frame_in_anim"
|
android:title="@string/menu_first_frame_in_anim"
|
||||||
app:showAsAction="never|withText" />
|
app:showAsAction="never|withText" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_optimise"
|
||||||
|
android:checkable="true"
|
||||||
|
android:title="@string/menu_optimise"
|
||||||
|
app:showAsAction="never|withText" />
|
||||||
</menu>
|
</menu>
|
|
@ -17,9 +17,12 @@
|
||||||
<string name="done">Done</string>
|
<string name="done">Done</string>
|
||||||
<string name="clear">Clear</string>
|
<string name="clear">Clear</string>
|
||||||
<string name="menu_first_frame_in_anim">First frame in animation</string>
|
<string name="menu_first_frame_in_anim">First frame in animation</string>
|
||||||
|
<string name="menu_optimise">Optimise animation</string>
|
||||||
<string name="add_frame">Add a frame to the animation</string>
|
<string name="add_frame">Add a frame to the animation</string>
|
||||||
<string name="create_animation">Create an animation</string>
|
<string name="create_animation">Create an animation</string>
|
||||||
|
|
||||||
|
<string name="file_size_kB">File size is %1$d kB</string>
|
||||||
|
|
||||||
<string name="open">open</string>
|
<string name="open">open</string>
|
||||||
<string name="close">close</string>
|
<string name="close">close</string>
|
||||||
<string name="delay">Delay (ms)</string>
|
<string name="delay">Delay (ms)</string>
|
||||||
|
|
Loading…
Reference in New Issue