changeset 17:86740f593b6c

Better memoization, more rational API.
author David Barts <n5jrn@me.com>
date Sun, 21 Feb 2021 22:14:07 -0800
parents 3ed74dc0e34a
children eedf995462d9 21be543e9127
files app/src/main/java/com/bartsent/simpleresizer/lib/LanczosKernel.kt app/src/main/java/com/bartsent/simpleresizer/lib/Resizer.kt app/src/main/java/com/bartsent/simpleresizer/lib/getScaledInstance.kt
diffstat 3 files changed, 16 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/app/src/main/java/com/bartsent/simpleresizer/lib/LanczosKernel.kt	Sun Feb 21 21:43:54 2021 -0800
+++ b/app/src/main/java/com/bartsent/simpleresizer/lib/LanczosKernel.kt	Sun Feb 21 22:14:07 2021 -0800
@@ -7,20 +7,22 @@
 class LanczosKernel: ScalingKernel {
     override val size = 3.0
     private val memory = HashMap<Double, Double>()
-    init {
-        memory.put(0.0, 1.0)
+
+    private fun sinc(x: Double): Double {
+        if (x == 0.0)
+            return 1.0
+        val pix = PI * x
+        return  sin(pix) / pix
     }
 
-    private fun sinc(x: Double): Double {
+    override fun weight(x: Double): Double {
+        if (abs(x) >= size)
+            return 0.0
         val remembered = memory[x]
         if (remembered != null)
             return remembered
-        val pix = PI * x
-        val calculated = sin(pix) / pix
+        val calculated = sinc(x) * sinc(x/size)
         memory[x] = calculated
         return calculated
     }
-
-    override fun weight(x: Double): Double =
-        if (abs(x) < size) sinc(x) * sinc(x/size) else 0.0
 }
\ No newline at end of file
--- a/app/src/main/java/com/bartsent/simpleresizer/lib/Resizer.kt	Sun Feb 21 21:43:54 2021 -0800
+++ b/app/src/main/java/com/bartsent/simpleresizer/lib/Resizer.kt	Sun Feb 21 22:14:07 2021 -0800
@@ -117,15 +117,13 @@
         }
     }
 
-    private val DEFAULT_KERNEL = LanczosKernel()
-
     /**
      * Resize the horizontal aspect.
      * @param       newWidth    Width of new image
      * @param       kernel      Scaling kernel to use (default: LanczosKernel)
      * @return                  A new Resizer object, resampled per specifications
      */
-    fun horizontal(newWidth: Int, kernel: ScalingKernel = DEFAULT_KERNEL): Resizer {
+    fun horizontal(newWidth: Int, kernel: ScalingKernel): Resizer {
         val dst = Resizer(newWidth, height)
         val weights = precomputeWeights(newWidth, width, kernel)
         for (y in 0 until height) {
@@ -140,7 +138,7 @@
      * @param       kernel      Scaling kernel to use (default: LanczosKernel)
      * @return                  A new Resizer object, resampled per specifications
      */
-    fun vertical(newHeight: Int, kernel: ScalingKernel = DEFAULT_KERNEL): Resizer {
+    fun vertical(newHeight: Int, kernel: ScalingKernel): Resizer {
         val dst = Resizer(width, newHeight)
         val weights = precomputeWeights(newHeight, height, kernel)
         for (x in 0 until width) {
--- a/app/src/main/java/com/bartsent/simpleresizer/lib/getScaledInstance.kt	Sun Feb 21 21:43:54 2021 -0800
+++ b/app/src/main/java/com/bartsent/simpleresizer/lib/getScaledInstance.kt	Sun Feb 21 22:14:07 2021 -0800
@@ -2,8 +2,6 @@
 
 import android.graphics.Bitmap
 
-private data class IndexWeight(var index: Int, var weight: Double)
-
 /**
  * A quality scaler, rather simpler than Image.getScaledInstance in that it has only
  * one (slow, high-quality) option.
@@ -11,7 +9,7 @@
  * @param       newHeight       Height of new bitmap
  * @return                      New bitmap
  */
-fun Bitmap.getScaledInstance(newWidth: Int, newHeight: Int): Bitmap {
+fun Bitmap.getScaledInstance(newWidth: Int, newHeight: Int, kernel: ScalingKernel = LanczosKernel()): Bitmap {
     if (newWidth <= 0)
         throw IllegalArgumentException("invalid width: $newWidth")
     if (newHeight <= 0)
@@ -19,10 +17,10 @@
     if (width == newWidth && height == newHeight)
         return this
     return if (width != newWidth) {
-        Resizer.fromBitmap(this).horizontal(newWidth).let {
-            if (height == newHeight) it else it.vertical(newHeight)
+        Resizer.fromBitmap(this).horizontal(newWidth, kernel).let {
+            if (height == newHeight) it else it.vertical(newHeight, kernel)
         }
     } else {
-        Resizer.fromBitmap(this).vertical(newHeight)
+        Resizer.fromBitmap(this).vertical(newHeight, kernel)
     } .toBitmap()
 }