Skip to content

Commit bd2bcb2

Browse files
authored
merge branch; Feature/session and image overlay [#138] (#149)
- **[Issue]** Phase 3 - **[Descriptions]** - Phase 3 작업내용 Merge - https://github.com/FoKE-Developers/FourCutTogether/milestone/4?closed=1
2 parents 2ca5da4 + 2c7b31a commit bd2bcb2

File tree

55 files changed

+992
-699
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+992
-699
lines changed

app/src/main/assets/sample_cut.png

861 KB
Loading
1.02 MB
Loading
725 KB
Loading

domain/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ dependencies {
1111
implementation(libs.androidx.core.ktx)
1212
implementation(libs.androidx.appcompat)
1313
implementation(libs.material)
14+
implementation(libs.androidx.ui.graphics.android)
1415
implementation(libs.camerax.view)
1516
implementation(libs.camerax.lifecycle)
17+
1618
testImplementation(libs.junit)
1719
androidTestImplementation(libs.androidx.junit)
1820
androidTestImplementation(libs.androidx.espresso.core)

domain/src/main/java/com/foke/together/domain/interactor/CaptureWithExternalCameraUseCase.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ class CaptureWithExternalCameraUseCase @Inject constructor(
1212
suspend operator fun invoke(fileName: String): Result<Unit> {
1313
externalCameraRepository.capture()
1414
.onSuccess {
15-
AppLog.i(TAG, "capture", "success: $it")
15+
AppLog.i(TAG, "invoke", "success: $it")
1616
imageRepository.cachingImage(it, fileName)
1717
return Result.success(Unit)
1818
}
1919
.onFailure {
2020
// TODO: handle network error
21-
AppLog.i(TAG, "capture", "failure: $it")
21+
AppLog.i(TAG, "invoke", "failure: $it")
2222
return Result.failure(it)
2323
}
2424
return Result.failure(Exception("Unknown error"))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.foke.together.domain.interactor
2+
3+
import android.net.Uri
4+
import androidx.compose.ui.graphics.asAndroidBitmap
5+
import androidx.compose.ui.graphics.layer.GraphicsLayer
6+
import com.foke.together.domain.output.ImageRepositoryInterface
7+
import com.foke.together.util.AppLog
8+
import com.foke.together.util.AppPolicy
9+
import javax.inject.Inject
10+
11+
class GenerateImageFromViewUseCase @Inject constructor(
12+
private val imageRepositoryInterface: ImageRepositoryInterface
13+
) {
14+
// TODO: UI -> UC -> UI 흐름으로 만들어보기
15+
suspend operator fun invoke(graphicsLayer: GraphicsLayer, filename: String? = null, isCutFrameForPrint: Boolean = false): Uri {
16+
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
17+
val finalCachedImageUri = imageRepositoryInterface.cachingImage(
18+
bitmap,
19+
filename ?: run {
20+
if (isCutFrameForPrint) AppPolicy.TWO_ROW_FINAL_IMAGE_NAME else AppPolicy.SINGLE_ROW_FINAL_IMAGE_NAME
21+
}
22+
)
23+
AppLog.d(TAG, "invoke" ,"finalCachedImageUri: $finalCachedImageUri")
24+
return finalCachedImageUri
25+
}
26+
27+
companion object {
28+
private val TAG = GenerateImageFromViewUseCase::class.java.simpleName
29+
}
30+
}

domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCase.kt renamed to domain/src/main/java/com/foke/together/domain/interactor/GeneratePhotoFrameUseCaseV1.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,35 @@ package com.foke.together.domain.interactor
33
import android.content.Context
44
import android.graphics.Bitmap
55
import android.net.Uri
6-
import com.foke.together.domain.interactor.entity.CutFrameType
76
import com.foke.together.domain.output.ImageRepositoryInterface
87
import com.foke.together.util.AppPolicy
98
import dagger.hilt.android.qualifiers.ApplicationContext
10-
import kotlinx.coroutines.flow.Flow
119
import javax.inject.Inject
1210

13-
class GeneratePhotoFrameUseCase @Inject constructor(
11+
@Deprecated("Not in use")
12+
class GeneratePhotoFrameUseCaseV1 @Inject constructor(
1413
@ApplicationContext private val context: Context,
1514
private val imageRepositoryInterface: ImageRepositoryInterface
1615
){
17-
fun getCutFrameType(): CutFrameType = imageRepositoryInterface.getCutFrameType()
18-
suspend fun setCutFrameType(type: Int) = imageRepositoryInterface.setCutFrameType(type)
19-
16+
// 촬영한 이미지 리스트 관리
17+
// TODO: 추후 세션 관리와 엮어서 처리하기
18+
@Deprecated("Not in use")
2019
fun getCapturedImageListUri(): List<Uri> = imageRepositoryInterface.getCachedImageUriList()
20+
@Deprecated("Not in use")
2121
suspend fun clearCapturedImageList() = imageRepositoryInterface.clearCacheDir()
22-
suspend fun saveGraphicsLayerImage(image: Bitmap, fileName: String) = imageRepositoryInterface.cachingImage(image, fileName)
23-
suspend fun saveFinalImage(image: Bitmap, fileName: String) = imageRepositoryInterface.saveToStorage(image, fileName)
2422

23+
24+
// 최종 이미지 URL 가져오기
25+
// TODO: 추후 세션 관리와 엮어서 처리하기
26+
@Deprecated("Not in use")
2527
fun getFinalSingleImageUri(): Uri {
2628
var finalSingleImageUri: Uri = Uri.EMPTY
2729
context.cacheDir.listFiles().forEach {
2830
file -> if (file.name.contains("${AppPolicy.SINGLE_ROW_FINAL_IMAGE_NAME}")) { finalSingleImageUri = Uri.fromFile(file) }
2931
}
3032
return finalSingleImageUri
3133
}
32-
34+
@Deprecated("Not in use")
3335
fun getFinalTwoImageUri(): Uri {
3436
var finalTwoImageUri: Uri = Uri.EMPTY
3537
context.cacheDir.listFiles().forEach {
Lines changed: 165 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,168 @@
11
package com.foke.together.domain.interactor.entity
22

3-
enum class CutFrameType {
4-
MAKER_FAIRE,
5-
FOURCUT_LIGHT,
6-
FOURCUT_DARK;
7-
8-
companion object {
9-
fun findBy(name: String): CutFrameType {
10-
return when (name) {
11-
MAKER_FAIRE.name -> MAKER_FAIRE
12-
FOURCUT_LIGHT.name -> FOURCUT_LIGHT
13-
FOURCUT_DARK.name -> FOURCUT_DARK
14-
else -> throw IllegalArgumentException("Unknown value: $name")
15-
}
16-
}
17-
fun findBy(ordinal: Int): CutFrameType {
18-
return when (ordinal) {
19-
MAKER_FAIRE.ordinal -> MAKER_FAIRE
20-
FOURCUT_LIGHT.ordinal -> FOURCUT_LIGHT
21-
FOURCUT_DARK.ordinal -> FOURCUT_DARK
22-
else -> throw IllegalArgumentException("Unknown value: $ordinal")
23-
}
24-
}
25-
}
3+
import androidx.annotation.DrawableRes
4+
import com.foke.together.domain.R
5+
6+
abstract class CutFrame(
7+
val index: Int,
8+
val frameTitle: String,
9+
val cutCount: Int,
10+
val width: Int,
11+
val height: Int,
12+
@DrawableRes val frameImageSrc: Int, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
13+
val photoPosition: List<PhotoPosition>,
14+
val additionalFrameImageSrc: List<Int>, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
15+
)
16+
17+
sealed class DefaultCutFrameSet (
18+
index: Int,
19+
frameTitle: String,
20+
cutCount: Int,
21+
width: Int,
22+
height: Int,
23+
frameImageSrc: Int, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
24+
photoPosition: List<PhotoPosition>,
25+
additionalFrameImageSrc: List<Int>, // !!!!! TODO: asset 에 추가 및 src 값을 넣어서 처리
26+
var isDateString: Boolean = false,
27+
val dateStringHeight: Int = 0,
28+
): CutFrame(index, frameTitle, cutCount, width, height, frameImageSrc, photoPosition, additionalFrameImageSrc) {
29+
val cutFrameSetTitle = "기본"
30+
val cutFrameCoverImageSrc = ""
31+
32+
// TODO: add information of frames
33+
data object FourCutLight: DefaultCutFrameSet(
34+
7,
35+
"같이네컷 화이트",
36+
4, 190, 570,
37+
R.drawable.fourcut_frame_medium_light,
38+
listOf(
39+
PhotoPosition(159, 106, 16, 36),
40+
PhotoPosition(159, 106, 16, 147),
41+
PhotoPosition(159, 106, 16, 258),
42+
PhotoPosition(159, 106, 16, 369),
43+
),
44+
emptyList()
45+
)
46+
47+
data object FourCurDark: DefaultCutFrameSet(
48+
8,
49+
"같이네컷 다크",
50+
4, 190, 570,
51+
R.drawable.fourcut_frame_medium_dark,
52+
listOf(
53+
PhotoPosition(159, 106, 16, 36),
54+
PhotoPosition(159, 106, 16, 147),
55+
PhotoPosition(159, 106, 16, 258),
56+
PhotoPosition(159, 106, 16, 369),
57+
),
58+
emptyList()
59+
)
60+
61+
data object MakerFaire: DefaultCutFrameSet(
62+
9,
63+
"Maker Faire Seoul 2024",
64+
4, 190, 570,
65+
R.drawable.maker_faire_frame,
66+
listOf(
67+
PhotoPosition(159, 106, 16, 36),
68+
PhotoPosition(159, 106, 16, 147),
69+
PhotoPosition(159, 106, 16, 258),
70+
PhotoPosition(159, 106, 16, 369),
71+
),
72+
emptyList()
73+
)
74+
75+
data object Bride1: DefaultCutFrameSet(
76+
3,
77+
"신부 1",
78+
4, 190, 570,
79+
R.drawable.bride1,
80+
listOf(
81+
PhotoPosition(172, 115, 9, 9),
82+
PhotoPosition(172, 115, 9, 133),
83+
PhotoPosition(172, 115, 9, 256),
84+
PhotoPosition(172, 115, 9, 383),
85+
),
86+
emptyList(),
87+
dateStringHeight = 498
88+
)
89+
90+
data object Bride2: DefaultCutFrameSet(
91+
4,
92+
"신부 2",
93+
4, 190, 570,
94+
R.drawable.bride2,
95+
listOf(
96+
PhotoPosition(172, 115, 9, 9),
97+
PhotoPosition(172, 115, 9, 133),
98+
PhotoPosition(172, 115, 9, 256),
99+
PhotoPosition(172, 115, 9, 383),
100+
),
101+
emptyList(),
102+
dateStringHeight = 495
103+
)
104+
105+
data object Groom1: DefaultCutFrameSet(
106+
5,
107+
"신랑 1",
108+
4, 190, 570,
109+
R.drawable.groom1,
110+
listOf(
111+
PhotoPosition(172, 115, 9, 9),
112+
PhotoPosition(172, 115, 9, 133),
113+
PhotoPosition(172, 115, 9, 256),
114+
PhotoPosition(172, 115, 9, 383),
115+
),
116+
emptyList(),
117+
dateStringHeight = 495
118+
)
119+
120+
data object Groom2: DefaultCutFrameSet(
121+
6,
122+
"신랑 2",
123+
4, 190, 570,
124+
R.drawable.groom2,
125+
listOf(
126+
PhotoPosition(172, 115, 9, 9),
127+
PhotoPosition(172, 115, 9, 133),
128+
PhotoPosition(172, 115, 9, 256),
129+
PhotoPosition(172, 115, 9, 383),
130+
),
131+
emptyList(),
132+
dateStringHeight = 495
133+
)
134+
135+
data object Wedding1: DefaultCutFrameSet(
136+
1,
137+
"웨딩 1",
138+
4, 190, 570,
139+
R.drawable.wedding,
140+
listOf(
141+
PhotoPosition(172, 115, 9, 9),
142+
PhotoPosition(172, 115, 9, 133),
143+
PhotoPosition(172, 115, 9, 256),
144+
PhotoPosition(172, 115, 9, 383),
145+
),
146+
listOf(
147+
R.drawable.wedding_overlay1
148+
),
149+
dateStringHeight = 495
150+
)
151+
152+
data object Wedding2: DefaultCutFrameSet(
153+
2,
154+
"웨딩 2",
155+
4, 190, 570,
156+
R.drawable.wedding,
157+
listOf(
158+
PhotoPosition(172, 115, 9, 9),
159+
PhotoPosition(172, 115, 9, 133),
160+
PhotoPosition(172, 115, 9, 256),
161+
PhotoPosition(172, 115, 9, 383),
162+
),
163+
listOf(
164+
R.drawable.wedding_overlay2
165+
),
166+
dateStringHeight = 495
167+
)
26168
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.foke.together.domain.interactor.entity
2+
3+
enum class CutFrameTypeV1 {
4+
MAKER_FAIRE,
5+
FOURCUT_LIGHT,
6+
FOURCUT_DARK;
7+
8+
companion object {
9+
fun findBy(name: String): CutFrameTypeV1 {
10+
return when (name) {
11+
MAKER_FAIRE.name -> MAKER_FAIRE
12+
FOURCUT_LIGHT.name -> FOURCUT_LIGHT
13+
FOURCUT_DARK.name -> FOURCUT_DARK
14+
else -> throw IllegalArgumentException("Unknown value: $name")
15+
}
16+
}
17+
fun findBy(ordinal: Int): CutFrameTypeV1 {
18+
return when (ordinal) {
19+
MAKER_FAIRE.ordinal -> MAKER_FAIRE
20+
FOURCUT_LIGHT.ordinal -> FOURCUT_LIGHT
21+
FOURCUT_DARK.ordinal -> FOURCUT_DARK
22+
else -> throw IllegalArgumentException("Unknown value: $ordinal")
23+
}
24+
}
25+
}
26+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.foke.together.domain.interactor.entity
2+
3+
data class PhotoPosition (
4+
val width: Int,
5+
val height: Int,
6+
val x: Int,
7+
val y: Int,
8+
)

0 commit comments

Comments
 (0)