Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
.externalNativeBuild
.cxx
local.properties

# Ignore Junie working files
.junie/guidelines.md
21 changes: 18 additions & 3 deletions app/src/main/java/de/berlindroid/zepatch/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaf
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.dp
import de.berlindroid.zepatch.PatchablePreviewMode.*
Expand Down Expand Up @@ -173,6 +175,10 @@ private fun PatchableDetail(
onBackClick: () -> Unit,
patchable: @Composable () -> Unit,
) {
var imageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
Comment thread
maiatoday marked this conversation as resolved.
var reducedImageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
var colorCount by remember { mutableIntStateOf(3) }

Scaffold(
modifier = modifier,
topBar = {
Expand Down Expand Up @@ -224,13 +230,22 @@ private fun PatchableDetail(
when (currentMode) {
COMPOSABLE -> PatchableBoundingBox(patchable = patchable)

BITMAP -> PatchableToBitmap(patchable = patchable)
BITMAP -> PatchableToBitmap(
onBitmap = { img -> imageBitmap = img },
patchable = patchable
Comment thread
maiatoday marked this conversation as resolved.
)

REDUCED_BITMAP -> PatchableToReducedBitmap(
patchable = patchable
image = imageBitmap,
colorCount = colorCount,
onColorCountChanged = { count -> colorCount = count },
onReducedBitmap = { img -> reducedImageBitmap = img },
)

STITCHES -> BitmapToStitches(patchable = patchable, name = name)
STITCHES -> BitmapToStitches(
reducedImageBitmap = reducedImageBitmap,
name = name
)
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/java/de/berlindroid/zepatch/patchable/Demo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand All @@ -23,7 +22,6 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand Down
118 changes: 67 additions & 51 deletions app/src/main/java/de/berlindroid/zepatch/ui/BitmapToStitches.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package de.berlindroid.zepatch.ui

import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log
Expand All @@ -11,15 +10,18 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
Expand All @@ -28,73 +30,70 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.core.graphics.scale
import com.embroidermodder.punching.reduceColors
import de.berlindroid.zepatch.stiches.StitchToPES
import de.berlindroid.zepatch.stiches.StitchToPES.createEmbroideryFromBitmap
import de.berlindroid.zepatch.utils.CaptureToBitmap

import kotlinx.coroutines.launch

@Composable
fun BitmapToStitches(
modifier: Modifier = Modifier,
name: String,
patchable: @Composable () -> Unit,
reducedImageBitmap: ImageBitmap? = null,
name: String
) {
val context = LocalContext.current
var bytes by remember { mutableStateOf<ByteArray?>(null) }
var displayImage by remember { mutableStateOf<ImageBitmap?>(null) }
val coroutineScope = rememberCoroutineScope()

val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
savePesAfterSelection(context, result, bytes)
}

var image by remember { mutableStateOf<ImageBitmap?>(null) }

Box(modifier = modifier.fillMaxWidth()) {
// Compose the content through the composable utility; it will invoke the callback when ready.
CaptureToBitmap(
modifier = Modifier.fillMaxWidth(),
onBitmap = { img ->
// TODO: PARRALELEIZE & VMIZE
val aspect = img.width / img.height.toFloat()

val reduced =
img.asAndroidBitmap()
.copy(Bitmap.Config.ARGB_8888, false)
.scale((512 * aspect).toInt(), 512, false)
.reduceColors(3) // TODO UI For color count selection

val embroidery = createEmbroideryFromBitmap(
name,
reduced,
mmWidth = 30f * aspect,
mmHeight = 30f,
mmDensity = 0.5f
)

val pes = StitchToPES.convert(context, embroidery)
if (pes == null || pes.isEmpty()) {
Log.e("EMBNO", "No pes found.")
} else {
bytes = pes
Column(modifier = modifier.fillMaxWidth()) {
reducedImageBitmap?.let {
Image(
bitmap = it,
contentDescription = "patch bitmap",
modifier = Modifier.fillMaxWidth()
)
}
Button(onClick = {
coroutineScope.launch {
reducedImageBitmap?.let {
val aspect = it.width / it.height.toFloat()
val embroidery = createEmbroideryFromBitmap(
name,
bitmap = it.asAndroidBitmap(),
mmWidth = 30f * aspect,
mmHeight = 30f,
mmDensity = 0.5f
)

val pes = StitchToPES.convert(context, embroidery)
if (pes == null || pes.isEmpty()) {
Log.e("EMBNO", "No pes found.")
} else {
bytes = pes
}

val png = StitchToPES.convert(context, embroidery, "png")
if (png == null || png.isEmpty()) {
Log.e("PNGNO", "No png returned.")
} else {
val decoded = BitmapFactory.decodeByteArray(png, 0, png.size)

displayImage = decoded
.scale(decoded.width * 2, decoded.height * 2)
.asImageBitmap()
}
}
}

val png = StitchToPES.convert(context, embroidery, "png")
if (png == null || png.isEmpty()) {
Log.e("PNGNO", "No png returned.")
} else {
val decoded = BitmapFactory.decodeByteArray(png, 0, png.size)
}) { Text("Do it") } // Compose the content through the composable utility; it will invoke the callback when ready.

image = decoded
.scale(decoded.width * 2, decoded.height * 2)
.asImageBitmap()
}
},
content = patchable
)

image?.let {
displayImage?.let {
Image(
bitmap = it,
contentDescription = "patch bitmap",
Expand Down Expand Up @@ -129,7 +128,6 @@ fun BitmapToStitches(
}
}


private fun savePesAfterSelection(context: Context, result: ActivityResult, bytes: ByteArray?) {
// TODO MOVE ME INTO VM

Expand Down Expand Up @@ -164,3 +162,21 @@ private fun savePesAfterSelection(context: Context, result: ActivityResult, byte
}
}

//@Preview(showBackground = true)
//@Composable
Comment thread
maiatoday marked this conversation as resolved.
Outdated
//private fun BitmapToStitchesPreview() {
// BitmapToStitches(Modifier, "Demo") {
// Box(
// modifier = Modifier
// .fillMaxWidth()
// .background(Color.Blue)
// ) {
// Text(
// "Preview Content",
// modifier = Modifier.padding(16.dp),
// color = Color.White
// )
// }
// }
//}

21 changes: 18 additions & 3 deletions app/src/main/java/de/berlindroid/zepatch/ui/PatchableToBitmap.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package de.berlindroid.zepatch.ui

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -20,15 +22,25 @@ import de.berlindroid.zepatch.utils.CaptureToBitmap
@Composable
fun PatchableToBitmap(
modifier: Modifier = Modifier,
onBitmap: (ImageBitmap) -> Unit = {},
patchable: @Composable () -> Unit,
) {
var image by remember { mutableStateOf<ImageBitmap?>(null) }
var capture by remember { mutableStateOf(false) }
Comment thread
maiatoday marked this conversation as resolved.
Outdated

Box(modifier = modifier.fillMaxWidth()) {
Column(modifier = modifier.fillMaxWidth()) {
Button(onClick = {
image = null
capture = true
}) { Text("Do it") }
// Compose the content through the composable utility; it will invoke the callback when ready.
CaptureToBitmap(
modifier = Modifier.fillMaxWidth(),
onBitmap = { img -> image = img },
capture = capture,
onBitmap = { img ->
image = img
capture = false
},
content = patchable
)

Expand All @@ -38,7 +50,10 @@ fun PatchableToBitmap(
contentDescription = "patch bitmap",
modifier = Modifier.fillMaxWidth()
)
onBitmap(it)
} ?: CircularProgressIndicator()

}
}


Loading