Skip to content

Commit 6fc14fe

Browse files
author
David Motsonashvili
committed
Add atachment list fo imagen3, also specify that image editing is vertex only
1 parent 55fa1ca commit 6fc14fe

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/FirebaseAISamples.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ val FIREBASE_AI_SAMPLES = listOf(
157157
}
158158
),
159159
Sample(
160-
title = "Imagen 3 - Inpainting",
160+
title = "Imagen 3 - Inpainting (Vertex AI)",
161161
description = "Replace the background of an image using Imagen 3",
162162
modelName = "imagen-3.0-capability-001",
163163
backend = GenerativeBackend.vertexAI(),
@@ -175,7 +175,7 @@ val FIREBASE_AI_SAMPLES = listOf(
175175
}
176176
),
177177
Sample(
178-
title = "Imagen 3 - Outpainting",
178+
title = "Imagen 3 - Outpainting (Vertex AI)",
179179
description = "Expand an image by drawing in more background",
180180
modelName = "imagen-3.0-capability-001",
181181
backend = GenerativeBackend.vertexAI(),
@@ -194,7 +194,7 @@ val FIREBASE_AI_SAMPLES = listOf(
194194
}
195195
),
196196
Sample(
197-
title = "Imagen 3 - Subject Reference",
197+
title = "Imagen 3 - Subject Reference (Vertex AI)",
198198
description = "generate an image using a referenced subject (must be an animal)",
199199
modelName = "imagen-3.0-capability-001",
200200
backend = GenerativeBackend.vertexAI(),
@@ -219,7 +219,7 @@ val FIREBASE_AI_SAMPLES = listOf(
219219
}
220220
),
221221
Sample(
222-
title = "Imagen 3 - Style Transfer",
222+
title = "Imagen 3 - Style Transfer (Vertex AI)",
223223
description = "Change the art style of an cat picture using a reference",
224224
modelName = "imagen-3.0-capability-001",
225225
backend = GenerativeBackend.vertexAI(),

firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/media/imagen/ImagenScreen.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import androidx.compose.material3.TextButton
2424
import androidx.compose.runtime.Composable
2525
import androidx.compose.runtime.getValue
2626
import androidx.compose.runtime.mutableStateOf
27+
import androidx.compose.runtime.rememberCoroutineScope
2728
import androidx.compose.runtime.saveable.rememberSaveable
2829
import androidx.compose.runtime.setValue
2930
import androidx.compose.ui.Alignment
@@ -33,6 +34,10 @@ import androidx.compose.ui.platform.LocalContext
3334
import androidx.compose.ui.unit.dp
3435
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3536
import androidx.lifecycle.viewmodel.compose.viewModel
37+
import com.google.firebase.quickstart.ai.feature.text.Attachment
38+
import com.google.firebase.quickstart.ai.feature.text.AttachmentsList
39+
import kotlinx.coroutines.flow.first
40+
import kotlinx.coroutines.launch
3641
import kotlinx.serialization.Serializable
3742

3843
@Serializable
@@ -48,8 +53,10 @@ fun ImagenScreen(
4853
val generatedImages by imagenViewModel.generatedBitmaps.collectAsStateWithLifecycle()
4954
val includeAttach by imagenViewModel.includeAttach.collectAsStateWithLifecycle()
5055
val allowEmptyPrompt by imagenViewModel.allowEmptyPrompt.collectAsStateWithLifecycle()
56+
val attachedImage by imagenViewModel.attachedImage.collectAsStateWithLifecycle()
5157
val context = LocalContext.current
5258
val contentResolver = context.contentResolver
59+
val scope = rememberCoroutineScope()
5360
val openDocument = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { optionalUri: Uri? ->
5461
optionalUri?.let { uri ->
5562
var fileName: String? = null
@@ -66,7 +73,9 @@ fun ImagenScreen(
6673

6774
contentResolver.openInputStream(uri)?.use { stream ->
6875
val bytes = stream.readBytes()
69-
imagenViewModel.attachImage(bytes)
76+
scope.launch {
77+
imagenViewModel.attachImage(bytes)
78+
}
7079
}
7180
}
7281
}
@@ -90,6 +99,9 @@ fun ImagenScreen(
9099
.fillMaxWidth()
91100
)
92101
if (includeAttach) {
102+
if (attachedImage != null) {
103+
AttachmentsList(listOf(Attachment("", attachedImage)))
104+
}
93105
TextButton(
94106
onClick = {
95107
openDocument.launch(arrayOf("image/*"))

firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/media/imagen/ImagenViewModel.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.google.firebase.ai.type.imagenGenerationConfig
2222
import com.google.firebase.quickstart.ai.FIREBASE_AI_SAMPLES
2323
import kotlinx.coroutines.flow.MutableStateFlow
2424
import kotlinx.coroutines.flow.StateFlow
25+
import kotlinx.coroutines.flow.first
2526
import kotlinx.coroutines.launch
2627

2728
@OptIn(PublicPreviewAPI::class)
@@ -44,17 +45,19 @@ class ImagenViewModel(
4445
private val _allowEmptyPrompt = MutableStateFlow(sample.allowEmptyPrompt)
4546
val allowEmptyPrompt: StateFlow<Boolean> = _allowEmptyPrompt
4647

48+
private val _attachedImage = MutableStateFlow<Bitmap?>(null)
49+
val attachedImage: StateFlow<Bitmap?> = _attachedImage
50+
4751
private val _generatedBitmaps = MutableStateFlow(listOf<Bitmap>())
4852
val generatedBitmaps: StateFlow<List<Bitmap>> = _generatedBitmaps
4953

5054
// Firebase AI Logic
5155
private val imagenModel: ImagenModel
52-
private var attachedImage: Bitmap?
5356

5457
init {
5558
val config = imagenGenerationConfig {
5659
numberOfImages = 4
57-
imageFormat = ImagenImageFormat.png()
60+
imageFormat = ImagenImasgeFormat.png()
5861
}
5962
val settings = ImagenSafetySettings(
6063
safetyFilterLevel = ImagenSafetyFilterLevel.BLOCK_LOW_AND_ABOVE,
@@ -67,14 +70,13 @@ class ImagenViewModel(
6770
generationConfig = config,
6871
safetySettings = settings
6972
)
70-
attachedImage = null
7173
}
7274

7375
fun generateImages(inputText: String) {
7476
viewModelScope.launch {
7577
_isLoading.value = true
7678
try {
77-
val imageResponse = sample.generateImages!!(imagenModel, inputText, attachedImage)
79+
val imageResponse = sample.generateImages!!(imagenModel, inputText, attachedImage.first())
7880
_generatedBitmaps.value = imageResponse.images.map { it.asBitmap() }
7981
_errorMessage.value = null // clear error message
8082
} catch (e: Exception) {
@@ -85,9 +87,9 @@ class ImagenViewModel(
8587
}
8688
}
8789

88-
fun attachImage(
90+
suspend fun attachImage(
8991
fileInBytes: ByteArray,
9092
) {
91-
attachedImage = BitmapFactory.decodeByteArray(fileInBytes, 0, fileInBytes.size)
93+
_attachedImage.emit(BitmapFactory.decodeByteArray(fileInBytes, 0, fileInBytes.size))
9294
}
9395
}

0 commit comments

Comments
 (0)