Imageviewer Bitmap Filter for uikit (#2575)

This commit is contained in:
Lee Taehoon
2022-12-26 17:34:19 +09:00
committed by GitHub
parent caea52c922
commit d6ff80c062
5 changed files with 121 additions and 10 deletions

View File

@@ -11,6 +11,9 @@ import example.imageviewer.model.ContentRepository
import example.imageviewer.model.State
import example.imageviewer.model.adapter
import example.imageviewer.model.createNetworkRepository
import example.imageviewer.model.filtration.BlurFilter
import example.imageviewer.model.filtration.GrayScaleFilter
import example.imageviewer.model.filtration.PixelFilter
import example.imageviewer.style.ImageViewerTheme
import example.imageviewer.view.Toast
import example.imageviewer.view.ToastState
@@ -39,18 +42,12 @@ internal fun ImageViewerIos() {
}
}
class StubFilter : BitmapFilter {
override fun apply(bitmap: ImageBitmap): ImageBitmap {
return bitmap
}
}
private fun getDependencies(ioScope: CoroutineScope, toastState: MutableState<ToastState>) = object : Dependencies {
fun getDependencies(ioScope: CoroutineScope, toastState: MutableState<ToastState>) = object : Dependencies {
override val ioScope: CoroutineScope = ioScope
override fun getFilter(type: FilterType): BitmapFilter = when (type) {
FilterType.GrayScale -> StubFilter()
FilterType.Pixel -> StubFilter()
FilterType.Blur -> StubFilter()
FilterType.GrayScale -> GrayScaleFilter()
FilterType.Pixel -> PixelFilter()
FilterType.Blur -> BlurFilter()
}
override val localization: Localization = object : Localization {

View File

@@ -0,0 +1,13 @@
package example.imageviewer.model.filtration
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asComposeImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import example.imageviewer.core.BitmapFilter
import example.imageviewer.utils.applyBlurFilter
class BlurFilter : BitmapFilter {
override fun apply(bitmap: ImageBitmap): ImageBitmap {
return applyBlurFilter(bitmap.asSkiaBitmap()).asComposeImageBitmap()
}
}

View File

@@ -0,0 +1,13 @@
package example.imageviewer.model.filtration
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asComposeImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import example.imageviewer.core.BitmapFilter
import example.imageviewer.utils.applyGrayScaleFilter
class GrayScaleFilter : BitmapFilter {
override fun apply(bitmap: ImageBitmap): ImageBitmap {
return applyGrayScaleFilter(bitmap.asSkiaBitmap()).asComposeImageBitmap()
}
}

View File

@@ -0,0 +1,13 @@
package example.imageviewer.model.filtration
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asComposeImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import example.imageviewer.core.BitmapFilter
import example.imageviewer.utils.applyPixelFilter
class PixelFilter : BitmapFilter {
override fun apply(bitmap: ImageBitmap): ImageBitmap {
return applyPixelFilter(bitmap.asSkiaBitmap()).asComposeImageBitmap()
}
}

View File

@@ -0,0 +1,75 @@
package example.imageviewer.utils
import org.jetbrains.skia.*
fun scaleBitmapAspectRatio(
bitmap: Bitmap,
width: Int,
height: Int
): Bitmap {
val boundWidth = width.toFloat()
val boundHeight = height.toFloat()
val ratioX = boundWidth / bitmap.width
val ratioY = boundHeight / bitmap.height
val ratio = if (ratioX < ratioY) ratioX else ratioY
val resultWidth = (bitmap.width * ratio).toInt()
val resultHeight = (bitmap.height * ratio).toInt()
val result = Bitmap().apply {
allocN32Pixels(resultWidth, resultHeight)
}
val canvas = Canvas(result)
canvas.drawImageRect(Image.makeFromBitmap(bitmap), result.bounds.toRect())
canvas.readPixels(result, 0, 0)
canvas.close()
return result
}
fun applyGrayScaleFilter(bitmap: Bitmap): Bitmap {
val imageInfo = ImageInfo(
width = bitmap.width,
height = bitmap.height,
colorInfo = ColorInfo(ColorType.GRAY_8, ColorAlphaType.PREMUL, null)
)
val result = Bitmap().apply {
allocPixels(imageInfo)
}
val canvas = Canvas(result)
canvas.drawImageRect(Image.makeFromBitmap(bitmap), bitmap.bounds.toRect())
canvas.readPixels(result, 0, 0)
canvas.close()
return result
}
fun applyPixelFilter(bitmap: Bitmap): Bitmap {
val width = bitmap.width
val height = bitmap.height
var result = scaleBitmapAspectRatio(bitmap, width / 20, height / 20)
result = scaleBitmapAspectRatio(result, width, height)
return result
}
fun applyBlurFilter(bitmap: Bitmap): Bitmap {
val result = Bitmap().apply {
allocN32Pixels(bitmap.width, bitmap.height)
}
val blur = Paint().apply {
imageFilter = ImageFilter.makeBlur(10f, 10f, FilterTileMode.CLAMP)
}
val canvas = Canvas(result)
canvas.saveLayer(null, blur)
canvas.drawImageRect(Image.makeFromBitmap(bitmap), bitmap.bounds.toRect())
canvas.restore()
canvas.readPixels(result, 0, 0)
canvas.close()
return result
}