@@ -2,7 +2,6 @@ package de.berlindroid.zepatch.ui
22
33import android.content.Context
44import android.content.Intent
5- import android.graphics.Bitmap
65import android.graphics.BitmapFactory
76import android.net.Uri
87import android.util.Log
@@ -11,90 +10,91 @@ import androidx.activity.compose.rememberLauncherForActivityResult
1110import androidx.activity.result.ActivityResult
1211import androidx.activity.result.contract.ActivityResultContracts
1312import androidx.compose.foundation.Image
14- import androidx.compose.foundation.layout.Box
13+ import androidx.compose.foundation.layout.Column
1514import androidx.compose.foundation.layout.fillMaxWidth
15+ import androidx.compose.material3.Button
1616import androidx.compose.material3.CircularProgressIndicator
1717import androidx.compose.material3.Icon
1818import androidx.compose.material3.IconButton
19+ import androidx.compose.material3.Text
1920import androidx.compose.runtime.Composable
2021import androidx.compose.runtime.getValue
2122import androidx.compose.runtime.mutableStateOf
2223import androidx.compose.runtime.remember
24+ import androidx.compose.runtime.rememberCoroutineScope
2325import androidx.compose.runtime.setValue
2426import androidx.compose.ui.Modifier
2527import androidx.compose.ui.graphics.ImageBitmap
2628import androidx.compose.ui.graphics.asAndroidBitmap
2729import androidx.compose.ui.graphics.asImageBitmap
2830import androidx.compose.ui.platform.LocalContext
2931import androidx.compose.ui.res.painterResource
32+ import androidx.compose.ui.tooling.preview.Preview
3033import androidx.core.graphics.scale
31- import com.embroidermodder.punching.reduceColors
3234import de.berlindroid.zepatch.stiches.StitchToPES
3335import de.berlindroid.zepatch.stiches.StitchToPES.createEmbroideryFromBitmap
34- import de.berlindroid.zepatch.utils.CaptureToBitmap
35-
36+ import kotlinx.coroutines.launch
3637
3738@Composable
3839fun BitmapToStitches (
3940 modifier : Modifier = Modifier ,
40- name : String ,
41- patchable : @Composable () -> Unit ,
41+ reducedImageBitmap : ImageBitmap ? = null ,
42+ name : String
4243) {
4344 val context = LocalContext .current
4445 var bytes by remember { mutableStateOf<ByteArray ?>(null ) }
46+ var displayImage by remember { mutableStateOf<ImageBitmap ?>(null ) }
47+ val coroutineScope = rememberCoroutineScope()
4548
4649 val launcher = rememberLauncherForActivityResult(
4750 contract = ActivityResultContracts .StartActivityForResult ()
4851 ) { result ->
4952 savePesAfterSelection(context, result, bytes)
5053 }
5154
52- var image by remember { mutableStateOf<ImageBitmap ?>(null ) }
53-
54- Box (modifier = modifier.fillMaxWidth()) {
55- // Compose the content through the composable utility; it will invoke the callback when ready.
56- CaptureToBitmap (
57- modifier = Modifier .fillMaxWidth(),
58- onBitmap = { img ->
59- // TODO: PARRALELEIZE & VMIZE
60- val aspect = img.width / img.height.toFloat()
61-
62- val reduced =
63- img.asAndroidBitmap()
64- .copy(Bitmap .Config .ARGB_8888 , false )
65- .scale((512 * aspect).toInt(), 512 , false )
66- .reduceColors(3 ) // TODO UI For color count selection
67-
68- val embroidery = createEmbroideryFromBitmap(
69- name,
70- reduced,
71- mmWidth = 30f * aspect,
72- mmHeight = 30f ,
73- mmDensity = 0.5f
74- )
75-
76- val pes = StitchToPES .convert(context, embroidery)
77- if (pes == null || pes.isEmpty()) {
78- Log .e(" EMBNO" , " No pes found." )
79- } else {
80- bytes = pes
55+ Column (modifier = modifier.fillMaxWidth()) {
56+ reducedImageBitmap?.let {
57+ Image (
58+ bitmap = it,
59+ contentDescription = " patch bitmap" ,
60+ modifier = Modifier .fillMaxWidth()
61+ )
62+ }
63+ Button (onClick = {
64+ coroutineScope.launch {
65+ reducedImageBitmap?.let {
66+ val aspect = it.width / it.height.toFloat()
67+ val embroidery = createEmbroideryFromBitmap(
68+ name,
69+ bitmap = it.asAndroidBitmap(),
70+ mmWidth = 30f * aspect,
71+ mmHeight = 30f ,
72+ mmDensity = 0.5f
73+ )
74+
75+ val pes = StitchToPES .convert(context, embroidery)
76+ if (pes == null || pes.isEmpty()) {
77+ Log .e(" EMBNO" , " No pes found." )
78+ } else {
79+ bytes = pes
80+ }
81+
82+ val png = StitchToPES .convert(context, embroidery, " png" )
83+ if (png == null || png.isEmpty()) {
84+ Log .e(" PNGNO" , " No png returned." )
85+ } else {
86+ val decoded = BitmapFactory .decodeByteArray(png, 0 , png.size)
87+
88+ displayImage = decoded
89+ .scale(decoded.width * 2 , decoded.height * 2 )
90+ .asImageBitmap()
91+ }
8192 }
93+ }
8294
83- val png = StitchToPES .convert(context, embroidery, " png" )
84- if (png == null || png.isEmpty()) {
85- Log .e(" PNGNO" , " No png returned." )
86- } else {
87- val decoded = BitmapFactory .decodeByteArray(png, 0 , png.size)
88-
89- image = decoded
90- .scale(decoded.width * 2 , decoded.height * 2 )
91- .asImageBitmap()
92- }
93- },
94- content = patchable
95- )
95+ }) { Text (" Do it" ) } // Compose the content through the composable utility; it will invoke the callback when ready.
9696
97- image ?.let {
97+ displayImage ?.let {
9898 Image (
9999 bitmap = it,
100100 contentDescription = " patch bitmap" ,
@@ -129,7 +129,6 @@ fun BitmapToStitches(
129129 }
130130}
131131
132-
133132private fun savePesAfterSelection (context : Context , result : ActivityResult , bytes : ByteArray? ) {
134133 // TODO MOVE ME INTO VM
135134
@@ -164,3 +163,10 @@ private fun savePesAfterSelection(context: Context, result: ActivityResult, byte
164163 }
165164}
166165
166+ @Preview
167+ @Composable
168+ fun BitmapToStitchesPreview () {
169+ val imageBitmap = ImageBitmap (width = 100 , height = 100 ) // Replace with a real ImageBitmap if needed
170+ BitmapToStitches (reducedImageBitmap = imageBitmap, name = " MyPatch" )
171+ }
172+
0 commit comments