Skip to content

Commit

Permalink
截图添加背景色
Browse files Browse the repository at this point in the history
  • Loading branch information
ssttkkl committed Aug 30, 2024
1 parent b8035d6 commit 20367d4
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 107 deletions.
7 changes: 7 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ kotlin {
dependsOn(commonMain)
}

val nonAndroidMain by creating {
dependsOn(commonMain)
}

if (enableAndroid) {
val androidMain by getting {
dependsOn(nonWasmJsMain)
Expand All @@ -138,12 +142,14 @@ kotlin {
if (enableIos) {
val iosMain by getting {
dependsOn(nonWasmJsMain)
dependsOn(nonAndroidMain)
}
}

if (enableDesktop) {
val desktopMain by getting {
dependsOn(nonWasmJsMain)
dependsOn(nonAndroidMain)
dependsOn(desktopAndWasmJsMain)
dependencies {
implementation(compose.desktop.currentOs)
Expand All @@ -158,6 +164,7 @@ kotlin {
if (enableWeb) {
val wasmJsMain by getting {
dependsOn(desktopAndWasmJsMain)
dependsOn(nonAndroidMain)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.ssttkkl.mahjongutils.app.utils.image

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.toArgb

actual suspend fun platformWithBackground(
imageBitmap: ImageBitmap,
background: Color
): ImageBitmap {
val newBitmap =
Bitmap.createBitmap(imageBitmap.width, imageBitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(newBitmap)

// 绘制背景
val paintBackground = Paint().apply {
color = background.toArgb()
style = Paint.Style.FILL
}
canvas.drawRect(
0f,
0f,
imageBitmap.width.toFloat(),
imageBitmap.height.toFloat(),
paintBackground
)

// 绘制原始位图
canvas.drawBitmap(imageBitmap.asAndroidBitmap(), 50f, 50f, null) // 偏移位置50, 50

return newBitmap.asImageBitmap()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.ssttkkl.mahjongutils.app.utils.image

import android.content.ContentValues
import android.graphics.Bitmap
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import io.ssttkkl.mahjongutils.app.MyApp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

actual object ImageUtils : CommonImageUtils() {
actual suspend fun save(imageBitmap: ImageBitmap, title: String): Boolean {
return withContext(Dispatchers.IO) {
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, title)
put(MediaStore.Images.Media.MIME_TYPE, "image/png")
put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
put(MediaStore.Images.Media.IS_PENDING, 1)
}

val uri: Uri = MyApp.current.contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
) ?: return@withContext false

uri.let {
try {
MyApp.current.contentResolver.openOutputStream(it)?.use {
imageBitmap.asAndroidBitmap().compress(Bitmap.CompressFormat.PNG, 100, it)
} ?: return@let false
values.clear()
values.put(MediaStore.Images.Media.IS_PENDING, 0)
MyApp.current.contentResolver.update(uri, values, null, null)
} catch (e: Exception) {
e.printStackTrace()
return@let false
}
}
return@withContext true
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.ExperimentalComposeApi
Expand All @@ -24,11 +25,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import dev.shreyaspatil.capturable.capturable
import dev.shreyaspatil.capturable.controller.CaptureController
import dev.shreyaspatil.capturable.controller.CaptureController.CaptureRequest
import dev.shreyaspatil.capturable.controller.rememberCaptureController
import io.ssttkkl.mahjongutils.app.utils.image.ImageUtils
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.completeWith
import kotlinx.coroutines.launch
Expand All @@ -48,6 +51,7 @@ fun LazyCapturableColumn(
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
captureBackground: Color? = MaterialTheme.colorScheme.background,
content: LazyListScope.() -> Unit
) {
var captureRequest: CaptureRequest? by remember { mutableStateOf(null) }
Expand Down Expand Up @@ -94,6 +98,9 @@ fun LazyCapturableColumn(
onDrawSignal?.await()
onDrawSignal = null
innerCaptureController.captureAsync(req.config).await()
}.mapCatching {
if (captureBackground == null) it
else ImageUtils.withBackground(it, captureBackground)
}
req.imageBitmapDeferred.completeWith(result)
captureRequest = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
package io.ssttkkl.mahjongutils.app.screens.base

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import dev.shreyaspatil.capturable.capturable
import io.ssttkkl.mahjongutils.app.components.appscaffold.AppBottomSheetState
import io.ssttkkl.mahjongutils.app.components.appscaffold.LocalAppState
import io.ssttkkl.mahjongutils.app.components.calculation.Calculation
import io.ssttkkl.mahjongutils.app.components.calculation.PopAndShowSnackbarOnFailure
import io.ssttkkl.mahjongutils.app.utils.Spacing
import io.ssttkkl.mahjongutils.app.utils.image.SavePhotoUtils
import io.ssttkkl.mahjongutils.app.utils.image.ImageUtils
import kotlinx.coroutines.launch
import mahjongutils.composeapp.generated.resources.Res
import mahjongutils.composeapp.generated.resources.icon_history_outlined
import mahjongutils.composeapp.generated.resources.label_clear
import mahjongutils.composeapp.generated.resources.label_history
import mahjongutils.composeapp.generated.resources.label_share
import mahjongutils.composeapp.generated.resources.text_save_result_success
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource

@Composable
Expand Down Expand Up @@ -58,7 +46,7 @@ fun <ARG, RES> NestedResultTopBarActions(model: NestedResultScreenModel<ARG, RES
model.parentScreenModel?.resultCaptureController?.let { controller ->
coroutineScope.launch {
val img = controller.captureAsync().await()
SavePhotoUtils.save(img, "result")
ImageUtils.save(img, "result")
appState.snackbarHostState.showSnackbar(saveSuccessMessage)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.ssttkkl.mahjongutils.app.utils.image

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap

expect suspend fun platformWithBackground(imageBitmap: ImageBitmap, background: Color): ImageBitmap

open class CommonImageUtils {
suspend fun withBackground(imageBitmap: ImageBitmap, background: Color): ImageBitmap =
platformWithBackground(imageBitmap, background)
}

expect object ImageUtils : CommonImageUtils {
suspend fun save(imageBitmap: ImageBitmap, title: String): Boolean
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import javax.imageio.ImageIO
import javax.swing.JFileChooser
import javax.swing.filechooser.FileNameExtensionFilter

actual object SavePhotoUtils {
actual object ImageUtils : CommonImageUtils() {
actual suspend fun save(imageBitmap: ImageBitmap, title: String): Boolean {
// 弹出文件选择框
val fileChooser = JFileChooser().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.ssttkkl.mahjongutils.app.utils.image

import androidx.compose.ui.graphics.ImageBitmap

actual object SavePhotoUtils {
actual suspend fun save(imageBitmap: ImageBitmap, title: String) {
actual object ImageUtils : CommonImageUtils() {
actual suspend fun save(imageBitmap: ImageBitmap, title: String): Boolean {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.ssttkkl.mahjongutils.app.utils.image

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.toComposeImageBitmap
import org.jetbrains.skia.Image
import org.jetbrains.skia.Paint
import org.jetbrains.skia.Rect
import org.jetbrains.skia.Surface

actual suspend fun platformWithBackground(
imageBitmap: ImageBitmap,
background: Color
): ImageBitmap {
// 创建一个新的图像位图用于存放背景和原始图像
val surface = Surface.makeRasterN32Premul(imageBitmap.width, imageBitmap.height)
val canvas = surface.canvas

// 绘制背景
val paintBackground = Paint().apply {
color = background.toArgb()
}
canvas.drawRect(
Rect.makeLTRB(
0f,
0f,
imageBitmap.width.toFloat(),
imageBitmap.height.toFloat()
), paintBackground
)

// 绘制原始图像
val skiaImage = Image.makeFromBitmap(imageBitmap.asSkiaBitmap())
canvas.drawImage(skiaImage, 0.0f, 0.0f)

// 返回新的 ImageBitmap
return surface.makeImageSnapshot().toComposeImageBitmap()
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private fun blobOptions(type: String): BlobPropertyBag = js(
"({ type })"
)

actual object SavePhotoUtils {
actual object ImageUtils : CommonImageUtils() {
private fun download(
buffer: JsAny?,
filename: String,
Expand Down

0 comments on commit 20367d4

Please sign in to comment.