diff --git a/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/bitmaps.kt b/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/bitmaps.kt index f7836ee1ab..5673404c27 100644 --- a/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/bitmaps.kt +++ b/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/bitmaps.kt @@ -19,6 +19,15 @@ package com.github.panpf.sketch.test.utils import android.graphics.Bitmap +fun Bitmap.toSizeString(): String = "${width}x${height}" + +@Suppress("USELESS_ELVIS") +val Bitmap.configOrNull: Bitmap.Config? + get() = config ?: null + +fun Bitmap.toShortInfoString(): String = "Bitmap(${width}x${height},$configOrNull)" + + val Bitmap.cornerA: Int get() = getPixel(0, 0) val Bitmap.cornerB: Int @@ -32,12 +41,4 @@ fun Bitmap.corners(block: Bitmap.() -> List): List { return block(this) } -fun Bitmap.toSizeString(): String = "${width}x${height}" - -fun Bitmap.corners(): List = listOf(cornerA, cornerB, cornerC, cornerD) - -@Suppress("USELESS_ELVIS") -val Bitmap.configOrNull: Bitmap.Config? - get() = config ?: null - -fun Bitmap.toShortInfoString(): String = "Bitmap(${width}x${height},$configOrNull)" \ No newline at end of file +fun Bitmap.corners(): List = listOf(cornerA, cornerB, cornerC, cornerD) \ No newline at end of file diff --git a/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/images.android.kt b/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/images.android.kt index dfbfac6dba..142e67debf 100644 --- a/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/images.android.kt +++ b/internal/test-utils-core/src/androidMain/kotlin/com/github/panpf/sketch/test/utils/images.android.kt @@ -1,6 +1,7 @@ package com.github.panpf.sketch.test.utils import android.graphics.Bitmap +import androidx.core.graphics.get import com.github.panpf.sketch.AndroidBitmapImage import com.github.panpf.sketch.Image import com.github.panpf.sketch.asSketchImage @@ -13,4 +14,13 @@ actual fun createImage(width: Int, height: Int): Image { actual fun createCacheValue(image: Image, extras: Map): MemoryCache.Value { return AndroidBitmapImageValue(image = image as AndroidBitmapImage, extras = extras) +} + +actual fun Image.hasAlpha(): Boolean = (this as AndroidBitmapImage).bitmap.hasAlpha() + +/** + * Returns the Color at the specified location. + */ +actual fun Image.getPixel(x: Int, y: Int): Int { + return (this as AndroidBitmapImage).bitmap.get(x, y) } \ No newline at end of file diff --git a/internal/test-utils-core/src/commonMain/kotlin/com/github/panpf/sketch/test/utils/images.common.kt b/internal/test-utils-core/src/commonMain/kotlin/com/github/panpf/sketch/test/utils/images.common.kt index ea806e01ac..bbd95e55f9 100644 --- a/internal/test-utils-core/src/commonMain/kotlin/com/github/panpf/sketch/test/utils/images.common.kt +++ b/internal/test-utils-core/src/commonMain/kotlin/com/github/panpf/sketch/test/utils/images.common.kt @@ -5,4 +5,26 @@ import com.github.panpf.sketch.cache.MemoryCache expect fun createImage(width: Int, height: Int): Image -expect fun createCacheValue(image: Image, extras: Map): MemoryCache.Value \ No newline at end of file +expect fun createCacheValue(image: Image, extras: Map): MemoryCache.Value + +val Image.cornerA: Int + get() = getPixel(0, 0) +val Image.cornerB: Int + get() = getPixel(width - 1, 0) +val Image.cornerC: Int + get() = getPixel(width - 1, height - 1) +val Image.cornerD: Int + get() = getPixel(0, height - 1) + +fun Image.corners(block: Image.() -> List): List { + return block(this) +} + +fun Image.corners(): List = listOf(cornerA, cornerB, cornerC, cornerD) + +expect fun Image.hasAlpha(): Boolean + +/** + * Returns the Color at the specified location. + */ +expect fun Image.getPixel(x: Int, y: Int): Int \ No newline at end of file diff --git a/internal/test-utils-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/test/utils/images.nonAndroid.kt b/internal/test-utils-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/test/utils/images.nonAndroid.kt index 1ace1ecfc2..250991e8e0 100644 --- a/internal/test-utils-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/test/utils/images.nonAndroid.kt +++ b/internal/test-utils-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/test/utils/images.nonAndroid.kt @@ -6,6 +6,8 @@ import com.github.panpf.sketch.SkiaBitmapImage import com.github.panpf.sketch.asSketchImage import com.github.panpf.sketch.cache.MemoryCache import com.github.panpf.sketch.cache.SkiaBitmapImageValue +import com.github.panpf.sketch.util.getPixel +import com.github.panpf.sketch.util.hasAlpha actual fun createImage(width: Int, height: Int): Image { return SkiaBitmap().apply { @@ -15,4 +17,14 @@ actual fun createImage(width: Int, height: Int): Image { actual fun createCacheValue(image: Image, extras: Map): MemoryCache.Value { return SkiaBitmapImageValue(image = image as SkiaBitmapImage, extras = extras) +} + +//actual fun Image.hasAlpha(): Boolean = !(this as SkiaBitmapImage).bitmap.isOpaque +actual fun Image.hasAlpha(): Boolean = (this as SkiaBitmapImage).bitmap.hasAlpha() + +/** + * Returns the Color at the specified location. + */ +actual fun Image.getPixel(x: Int, y: Int): Int { + return (this as SkiaBitmapImage).bitmap.getPixel(x, y) } \ No newline at end of file diff --git a/sketch-core/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/core/android/test/transform/BlurTransformationTest.kt b/sketch-core/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/core/android/test/transform/BlurTransformationTest.kt deleted file mode 100644 index c718dc5994..0000000000 --- a/sketch-core/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/core/android/test/transform/BlurTransformationTest.kt +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2024 panpf - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.panpf.sketch.core.android.test.transform - -import android.graphics.BitmapFactory -import android.graphics.Color -import androidx.core.graphics.ColorUtils -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.github.panpf.sketch.asSketchImage -import com.github.panpf.sketch.getBitmapOrThrow -import com.github.panpf.sketch.images.ResourceImages -import com.github.panpf.sketch.request.ImageRequest -import com.github.panpf.sketch.test.singleton.getTestContextAndSketch -import com.github.panpf.sketch.test.utils.corners -import com.github.panpf.sketch.test.utils.size -import com.github.panpf.sketch.test.utils.toRequestContext -import com.github.panpf.sketch.transform.BlurTransformation -import com.github.panpf.sketch.transform.createBlurTransformed -import com.github.panpf.sketch.transform.getBlurTransformed -import com.github.panpf.sketch.util.Size -import com.github.panpf.tools4j.test.ktx.assertThrow -import kotlinx.coroutines.runBlocking -import org.junit.Assert -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class BlurTransformationTest { - - @Test - fun testConstructor() { - assertThrow(IllegalArgumentException::class) { - BlurTransformation(0) - } - assertThrow(IllegalArgumentException::class) { - BlurTransformation(101) - } - assertThrow(IllegalArgumentException::class) { - BlurTransformation( - hasAlphaBitmapBgColor = ColorUtils.setAlphaComponent(Color.BLACK, 244) - ) - } - BlurTransformation(12).apply { - Assert.assertEquals(12, radius) - Assert.assertEquals(Color.BLACK, hasAlphaBitmapBgColor) - Assert.assertNull(maskColor) - } - BlurTransformation(20, hasAlphaBitmapBgColor = null, maskColor = Color.GREEN).apply { - Assert.assertEquals(20, radius) - Assert.assertNull(hasAlphaBitmapBgColor) - Assert.assertEquals(Color.GREEN, maskColor) - } - } - - @Test - fun testKeyAndToString() { - BlurTransformation().apply { - Assert.assertEquals("BlurTransformation(15,${Color.BLACK},null)", key) - Assert.assertEquals("BlurTransformation(15,${Color.BLACK},null)", toString()) - } - BlurTransformation(20, hasAlphaBitmapBgColor = null, maskColor = Color.GREEN).apply { - Assert.assertEquals("BlurTransformation(20,null,${Color.GREEN})", key) - Assert.assertEquals("BlurTransformation(20,null,${Color.GREEN})", toString()) - } - } - - @Test - fun testTransform() { - val (context, sketch) = getTestContextAndSketch() - val request = ImageRequest(context, ResourceImages.jpeg.uri) - - // isMutable false - val inBitmap = context.assets.open(ResourceImages.jpeg.resourceName).use { - BitmapFactory.decodeStream(it) - }.apply { - Assert.assertNotEquals( - listOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT), - this.corners() - ) - Assert.assertEquals( - Size(1291, 1936), - this.size - ) - Assert.assertFalse(this.isMutable) - } - val inBitmapCorners = inBitmap.corners() - runBlocking { - BlurTransformation( - 30, - maskColor = ColorUtils.setAlphaComponent(Color.BLUE, 80) - ).transform(sketch, request.toRequestContext(sketch), inBitmap.asSketchImage()) - }.apply { - Assert.assertNotSame(inBitmap, image.getBitmapOrThrow()) - Assert.assertNotEquals(inBitmapCorners, image.getBitmapOrThrow().corners()) - Assert.assertEquals(Size(1291, 1936), image.getBitmapOrThrow().size) - Assert.assertEquals( - createBlurTransformed( - 30, - Color.BLACK, - ColorUtils.setAlphaComponent(Color.BLUE, 80) - ), transformed - ) - } - - // isMutable true - val mutableInBitmap = context.assets.open(ResourceImages.jpeg.resourceName).use { - BitmapFactory.decodeStream(it, null, BitmapFactory.Options().apply { - inMutable = true - }) - }!!.apply { - Assert.assertTrue(this.isMutable) - } - runBlocking { - BlurTransformation(30).transform( - sketch, - request.toRequestContext(sketch), - mutableInBitmap.asSketchImage() - ) - }.apply { - Assert.assertSame(mutableInBitmap, this.image.getBitmapOrThrow()) - } - - // hasAlphaBitmapBgColor - val hasAlphaBitmap1 = context.assets.open(ResourceImages.png.resourceName).use { - BitmapFactory.decodeStream(it, null, null) - }!!.apply { - Assert.assertTrue(this.hasAlpha()) - } - val hasAlphaBitmapBlurred1 = runBlocking { - BlurTransformation(30).transform( - sketch, - request.toRequestContext(sketch), - hasAlphaBitmap1.asSketchImage() - ) - }.apply { - Assert.assertTrue(this.image.getBitmapOrThrow().hasAlpha()) - }.image.getBitmapOrThrow() - - val hasAlphaBitmap2 = context.assets.open(ResourceImages.png.resourceName).use { - BitmapFactory.decodeStream(it, null, null) - }!!.apply { - Assert.assertTrue(this.hasAlpha()) - } - val hasAlphaBitmapBlurred2 = runBlocking { - BlurTransformation(30, hasAlphaBitmapBgColor = null) - .transform( - sketch, - request.toRequestContext(sketch), - hasAlphaBitmap2.asSketchImage() - ) - }.apply { - Assert.assertTrue(this.image.getBitmapOrThrow().hasAlpha()) - }.image.getBitmapOrThrow() - Assert.assertNotEquals(hasAlphaBitmapBlurred1.corners(), hasAlphaBitmapBlurred2.corners()) - } - - @Test - fun testEqualsAndHashCode() { - val element1 = BlurTransformation(20, null, null) - val element11 = BlurTransformation(20, null, null) - val element2 = BlurTransformation(10, Color.GREEN, null) - val element3 = BlurTransformation(20, Color.BLACK, Color.BLUE) - val element4 = BlurTransformation(20, Color.BLACK, Color.WHITE) - - Assert.assertNotSame(element1, element11) - Assert.assertNotSame(element1, element2) - Assert.assertNotSame(element1, element3) - Assert.assertNotSame(element1, element4) - Assert.assertNotSame(element11, element2) - Assert.assertNotSame(element11, element3) - Assert.assertNotSame(element11, element4) - Assert.assertNotSame(element2, element3) - Assert.assertNotSame(element2, element4) - Assert.assertNotSame(element3, element4) - - Assert.assertEquals(element1, element1) - Assert.assertEquals(element1, element11) - Assert.assertNotEquals(element1, element2) - Assert.assertNotEquals(element1, element3) - Assert.assertNotEquals(element1, element4) - Assert.assertNotEquals(element2, element11) - Assert.assertNotEquals(element2, element3) - Assert.assertNotEquals(element2, element4) - Assert.assertNotEquals(element3, element4) - Assert.assertNotEquals(element1, null) - Assert.assertNotEquals(element1, Any()) - - Assert.assertEquals(element1.hashCode(), element1.hashCode()) - Assert.assertEquals(element1.hashCode(), element11.hashCode()) - Assert.assertNotEquals(element1.hashCode(), element2.hashCode()) - Assert.assertNotEquals(element2.hashCode(), element11.hashCode()) - Assert.assertNotEquals(element2.hashCode(), element3.hashCode()) - } - - @Test - fun testBlurTransformed() { - Assert.assertEquals("BlurTransformed(1,null,null)", createBlurTransformed(1, null, null)) - Assert.assertEquals("BlurTransformed(2,null,null)", createBlurTransformed(2, null, null)) - Assert.assertEquals("BlurTransformed(4,null,null)", createBlurTransformed(4, null, null)) - Assert.assertEquals("BlurTransformed(8,null,null)", createBlurTransformed(8, null, null)) - - Assert.assertEquals(null, listOf().getBlurTransformed()) - Assert.assertEquals( - "BlurTransformed(2,null,null)", - listOf(createBlurTransformed(2, null, null)).getBlurTransformed() - ) - Assert.assertEquals( - "BlurTransformed(16,null,null)", - listOf( - "disruptive1", - createBlurTransformed(16, null, null), - "disruptive2" - ).getBlurTransformed() - ) - } -} \ No newline at end of file diff --git a/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/transform/BlurTransformation.common.kt b/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/transform/BlurTransformation.common.kt index de9d4784f4..8d1b7448d4 100644 --- a/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/transform/BlurTransformation.common.kt +++ b/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/transform/BlurTransformation.common.kt @@ -31,6 +31,8 @@ internal expect fun blurTransformation( /** * Bitmap blur transformation + * + * @see com.github.panpf.sketch.core.common.test.transform.BlurTransformationTest */ class BlurTransformation constructor( /** Blur radius */ @@ -86,12 +88,27 @@ class BlurTransformation constructor( } } +/** + * Create a blur transform record + * + * @see com.github.panpf.sketch.core.common.test.transform.BlurTransformationTest.testBlurTransformed + */ fun createBlurTransformed( radius: Int, hasAlphaBitmapBgColor: Int?, maskColor: Int? ) = "BlurTransformed($radius,$hasAlphaBitmapBgColor,$maskColor)" +/** + * Check if the transformed string is a blur transformation + * + * @see com.github.panpf.sketch.core.common.test.transform.BlurTransformationTest.testBlurTransformed + */ fun isBlurTransformed(transformed: String): Boolean = transformed.startsWith("BlurTransformed(") +/** + * Get the blur transformation record from the transformed record list + * + * @see com.github.panpf.sketch.core.common.test.transform.BlurTransformationTest.testBlurTransformed + */ fun List.getBlurTransformed(): String? = find { isBlurTransformed(it) } \ No newline at end of file diff --git a/sketch-core/src/commonTest/kotlin/com/github/panpf/sketch/core/common/test/transform/BlurTransformationTest.kt b/sketch-core/src/commonTest/kotlin/com/github/panpf/sketch/core/common/test/transform/BlurTransformationTest.kt new file mode 100644 index 0000000000..bdc534d5bb --- /dev/null +++ b/sketch-core/src/commonTest/kotlin/com/github/panpf/sketch/core/common/test/transform/BlurTransformationTest.kt @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2024 panpf + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.panpf.sketch.core.common.test.transform + +import com.github.panpf.sketch.images.ResourceImages +import com.github.panpf.sketch.request.ImageRequest +import com.github.panpf.sketch.size +import com.github.panpf.sketch.test.singleton.getTestContextAndSketch +import com.github.panpf.sketch.test.utils.corners +import com.github.panpf.sketch.test.utils.decode +import com.github.panpf.sketch.test.utils.hasAlpha +import com.github.panpf.sketch.test.utils.toRequestContext +import com.github.panpf.sketch.transform.BlurTransformation +import com.github.panpf.sketch.transform.createBlurTransformed +import com.github.panpf.sketch.transform.getBlurTransformed +import com.github.panpf.sketch.util.Size +import kotlinx.coroutines.test.runTest +import org.jetbrains.skia.Color +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertFalse +import kotlin.test.assertNotEquals +import kotlin.test.assertNotSame +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class BlurTransformationTest { + + @Test + fun testConstructor() { + assertFailsWith(IllegalArgumentException::class) { + BlurTransformation(0) + } + assertFailsWith(IllegalArgumentException::class) { + BlurTransformation(101) + } + assertFailsWith(IllegalArgumentException::class) { + BlurTransformation( + hasAlphaBitmapBgColor = Color.withA(color = Color.BLACK, a = 244) + ) + } + BlurTransformation(12).apply { + assertEquals(12, radius) + assertEquals(Color.BLACK, hasAlphaBitmapBgColor) + assertNull(maskColor) + } + BlurTransformation(20, hasAlphaBitmapBgColor = null, maskColor = Color.GREEN).apply { + assertEquals(20, radius) + assertNull(hasAlphaBitmapBgColor) + assertEquals(Color.GREEN, maskColor) + } + } + + @Test + fun testKeyAndToString() { + BlurTransformation().apply { + assertEquals("BlurTransformation(15,${Color.BLACK},null)", key) + assertEquals("BlurTransformation(15,${Color.BLACK},null)", toString()) + } + BlurTransformation(20, hasAlphaBitmapBgColor = null, maskColor = Color.GREEN).apply { + assertEquals("BlurTransformation(20,null,${Color.GREEN})", key) + assertEquals("BlurTransformation(20,null,${Color.GREEN})", toString()) + } + } + + @Test + fun testTransform() = runTest { + val (context, sketch) = getTestContextAndSketch() + val jpegRequest = ImageRequest(context, ResourceImages.jpeg.uri) { + size(Size.Origin) + } + val jpegRequestContext = jpegRequest.toRequestContext(sketch) + + val inBitmap = jpegRequest.decode(sketch).image.apply { + assertFalse(this.hasAlpha()) + } + inBitmap.apply { + assertNotEquals( + listOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT), + this.corners() + ) + assertEquals( + Size(1291, 1936), + this.size + ) + } + val inBitmapCorners = inBitmap.corners() + + val transformResult = BlurTransformation( + radius = 30, + maskColor = Color.withA(Color.BLUE, 80) + ).transform(sketch, jpegRequestContext, inBitmap) + transformResult.apply { + assertNotSame(inBitmap, image) + assertNotEquals(inBitmapCorners, image.corners()) + assertEquals(Size(1291, 1936), image.size) + assertEquals( + expected = createBlurTransformed( + radius = 30, + hasAlphaBitmapBgColor = Color.BLACK, + maskColor = Color.withA(Color.BLUE, 80) + ), + actual = transformed + ) + } + + // hasAlphaBitmapBgColor + val pngRequest = ImageRequest(context, ResourceImages.png.uri) { + size(Size.Origin) + } + val pngRequestContext = pngRequest.toRequestContext(sketch) + val hasAlphaBitmap1 = pngRequest.decode(sketch).image.apply { + assertTrue(this.hasAlpha()) + } + val hasAlphaBitmapBlurred1 = BlurTransformation(30).transform( + sketch = sketch, + requestContext = pngRequestContext, + input = hasAlphaBitmap1 + ).apply { + assertFalse(this.image.hasAlpha()) + }.image + + val hasAlphaBitmap2 = pngRequest.decode(sketch).image.apply { + assertTrue(this.hasAlpha()) + } + val hasAlphaBitmapBlurred2 = BlurTransformation(30, hasAlphaBitmapBgColor = null) + .transform( + sketch, + pngRequestContext, + hasAlphaBitmap2 + ).apply { + assertTrue(this.image.hasAlpha()) + }.image + assertNotEquals(hasAlphaBitmapBlurred1.corners(), hasAlphaBitmapBlurred2.corners()) + } + + @Test + fun testEqualsAndHashCode() { + val element1 = BlurTransformation(20, null, null) + val element11 = BlurTransformation(20, null, null) + val element2 = BlurTransformation(10, Color.GREEN, null) + val element3 = BlurTransformation(20, Color.BLACK, Color.BLUE) + val element4 = BlurTransformation(20, Color.BLACK, Color.WHITE) + + assertNotSame(element1, element11) + assertNotSame(element1, element2) + assertNotSame(element1, element3) + assertNotSame(element1, element4) + assertNotSame(element11, element2) + assertNotSame(element11, element3) + assertNotSame(element11, element4) + assertNotSame(element2, element3) + assertNotSame(element2, element4) + assertNotSame(element3, element4) + + assertEquals(element1, element1) + assertEquals(element1, element11) + assertNotEquals(element1, element2) + assertNotEquals(element1, element3) + assertNotEquals(element1, element4) + assertNotEquals(element2, element11) + assertNotEquals(element2, element3) + assertNotEquals(element2, element4) + assertNotEquals(element3, element4) + assertNotEquals(element1, null as Any?) + assertNotEquals(element1, Any()) + + assertEquals(element1.hashCode(), element1.hashCode()) + assertEquals(element1.hashCode(), element11.hashCode()) + assertNotEquals(element1.hashCode(), element2.hashCode()) + assertNotEquals(element2.hashCode(), element11.hashCode()) + assertNotEquals(element2.hashCode(), element3.hashCode()) + } + + @Test + fun testBlurTransformed() { + assertEquals("BlurTransformed(1,null,null)", createBlurTransformed(1, null, null)) + assertEquals("BlurTransformed(2,null,null)", createBlurTransformed(2, null, null)) + assertEquals("BlurTransformed(4,null,null)", createBlurTransformed(4, null, null)) + assertEquals("BlurTransformed(8,null,null)", createBlurTransformed(8, null, null)) + + assertEquals(null, listOf().getBlurTransformed()) + assertEquals( + "BlurTransformed(2,null,null)", + listOf(createBlurTransformed(2, null, null)).getBlurTransformed() + ) + assertEquals( + "BlurTransformed(16,null,null)", + listOf( + "disruptive1", + createBlurTransformed(16, null, null), + "disruptive2" + ).getBlurTransformed() + ) + } +} \ No newline at end of file diff --git a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/BlurTransformationDesktopTest.kt b/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/BlurTransformationDesktopTest.kt deleted file mode 100644 index e642ec8cee..0000000000 --- a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/BlurTransformationDesktopTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.desktop.test.transform - -class BlurTransformationDesktopTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/CircleCropTransformationDesktopTest.kt b/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/CircleCropTransformationDesktopTest.kt deleted file mode 100644 index f6eacc98ef..0000000000 --- a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/CircleCropTransformationDesktopTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.desktop.test.transform - -class CircleCropTransformationDesktopTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/MaskTransformationDesktopTest.kt b/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/MaskTransformationDesktopTest.kt deleted file mode 100644 index 28c2ceda3c..0000000000 --- a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/MaskTransformationDesktopTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.desktop.test.transform - -class MaskTransformationDesktopTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RotateTransformationDesktopTest.kt b/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RotateTransformationDesktopTest.kt deleted file mode 100644 index 9c280643fd..0000000000 --- a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RotateTransformationDesktopTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.desktop.test.transform - -class RotateTransformationDesktopTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RoundedCornersTransformationDesktopTest.kt b/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RoundedCornersTransformationDesktopTest.kt deleted file mode 100644 index 72b19677dc..0000000000 --- a/sketch-core/src/desktopTest/kotlin/com/github/panpf/sketch/core/desktop/test/transform/RoundedCornersTransformationDesktopTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.desktop.test.transform - -class RoundedCornersTransformationDesktopTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/BlurTransformationJsCommonTest.kt b/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/BlurTransformationJsCommonTest.kt deleted file mode 100644 index 9c3d1332fa..0000000000 --- a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/BlurTransformationJsCommonTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.jscommon.test.transform - -class BlurTransformationJsCommonTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/CircleCropTransformationJsCommonTest.kt b/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/CircleCropTransformationJsCommonTest.kt deleted file mode 100644 index ad93f0786d..0000000000 --- a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/CircleCropTransformationJsCommonTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.jscommon.test.transform - -class CircleCropTransformationJsCommonTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/MaskTransformationJsCommonTest.kt b/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/MaskTransformationJsCommonTest.kt deleted file mode 100644 index 3c6a2243cc..0000000000 --- a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/MaskTransformationJsCommonTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.jscommon.test.transform - -class MaskTransformationJsCommonTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RotateTransformationJsCommonTest.kt b/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RotateTransformationJsCommonTest.kt deleted file mode 100644 index b49ae7b5d4..0000000000 --- a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RotateTransformationJsCommonTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.jscommon.test.transform - -class RotateTransformationJsCommonTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RoundedCornersTransformationJsCommonTest.kt b/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RoundedCornersTransformationJsCommonTest.kt deleted file mode 100644 index 02c7e7b027..0000000000 --- a/sketch-core/src/jsCommonTest/kotlin/com/github/panpf/sketch/core/jscommon/test/transform/RoundedCornersTransformationJsCommonTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.panpf.sketch.core.jscommon.test.transform - -class RoundedCornersTransformationJsCommonTest { - // TODO test -} \ No newline at end of file diff --git a/sketch-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/util/skia_bitmaps.kt b/sketch-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/util/skia_bitmaps.kt index 270c8d5d65..b08bfe7e63 100644 --- a/sketch-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/util/skia_bitmaps.kt +++ b/sketch-core/src/nonAndroidMain/kotlin/com/github/panpf/sketch/util/skia_bitmaps.kt @@ -27,6 +27,7 @@ import org.jetbrains.skia.Canvas import org.jetbrains.skia.Color import org.jetbrains.skia.ColorType import org.jetbrains.skia.Image +import org.jetbrains.skia.ImageInfo import org.jetbrains.skia.Paint import org.jetbrains.skia.RRect import kotlin.math.ceil @@ -41,7 +42,7 @@ internal fun SkiaBitmap.copied(): SkiaBitmap { return outBitmap } -internal fun SkiaBitmap.hasAlpha(): Boolean { +fun SkiaBitmap.hasAlpha(): Boolean { val height = this.height val width = this.width var hasAlpha = false @@ -258,6 +259,19 @@ internal fun SkiaBitmap.scaled(scaleFactor: Float): SkiaBitmap { return outBitmap } +/** + * Returns the Color at the specified location. + */ +fun SkiaBitmap.getPixel(x: Int, y: Int): Int { + val bitmap = this + val stride = 1 + val bytesPerPixel = 4 + val colorInfo = bitmap.colorInfo + val imageInfo = ImageInfo(colorInfo, 1, 1) + val bytes = bitmap.readPixels(imageInfo, stride * bytesPerPixel, x, y)!! + val intColorPixels = convertToIntColorPixels(bytes, colorInfo.colorType) + return intColorPixels.first() +} private fun convertToIntColorPixels(byteArray: ByteArray, colorType: ColorType): IntArray { return when (colorType) {