1. Introduzione
Che cos'è MediaPipe?
MediaPipe Solutions ti consente di applicare soluzioni di machine learning (ML) alle tue app. Fornisce un framework per la configurazione di pipeline di elaborazione predefinite che forniscono output immediati, coinvolgenti e utili agli utenti. Puoi persino personalizzare molte di queste soluzioni con MediaPipe Model Maker per aggiornare i modelli predefiniti.
La generazione di immagini da testo è una delle numerose attività di ML offerte da MediaPipe Solutions.
In questo codelab, inizierai con un'app per Android quasi vuota, per poi procedere in più passaggi fino a quando non sarai in grado di generare nuove immagini direttamente sul tuo dispositivo Android.
Obiettivi didattici
- Come implementare la generazione da testo a immagine eseguita localmente in un'app per Android con MediaPipe Tasks.
Che cosa ti serve
- Una versione installata di Android Studio (questo codelab è stato scritto e testato con Android Studio Giraffe).
- Un dispositivo Android con almeno 8 GB di RAM.
- Conoscenza di base dello sviluppo per Android e capacità di eseguire uno script Python precompilato.
2. Aggiungere MediaPipe Tasks all'app per Android
Scaricare l'app di base per Android
Questo codelab inizierà con un esempio predefinito costituito dall'interfaccia utente che verrà utilizzata per una versione di base della generazione di immagini. Puoi trovare l'app iniziale nel repository ufficiale di esempi di MediaPipe qui. Clona il repository o scarica il file ZIP facendo clic su Codice > Scarica ZIP.
Importare l'app in Android Studio
- Apri Android Studio.
- Nella schermata Benvenuto in Android Studio, seleziona Apri nell'angolo in alto a destra.

- Vai alla posizione in cui hai clonato o scaricato il repository e apri la directory codelabs/image_generation_basic/android/start.
- In questa fase, l'app non deve essere compilata perché non hai ancora incluso la dipendenza MediaPipe Tasks.
Per risolvere il problema e far funzionare l'app, vai al file build.gradle e scorri verso il basso fino a // Step 1 - Add dependency. Da qui, includi la seguente riga e poi premi il pulsante Sincronizza ora visualizzato nel banner nella parte superiore di Android Studio.
// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
Una volta completata la sincronizzazione, verifica che tutto sia stato aperto e installato correttamente facendo clic sulla freccia verde Esegui (
) in alto a destra di Android Studio. Dovresti vedere l'app aperta su una schermata con due pulsanti di opzione e un pulsante etichettato INITIALIZE. Se fai clic su questo pulsante, dovresti essere indirizzato immediatamente a un'interfaccia utente separata costituita da un prompt di testo e altre opzioni insieme a un pulsante con l'etichetta GENERA.

Purtroppo, questa è la misura dell'app di base, quindi è il momento di imparare a completarla e iniziare a generare nuove immagini sul tuo dispositivo.
3. Configurazione del Generatore di immagini
Per questo esempio, la maggior parte del lavoro di generazione delle immagini verrà svolto nel file ImageGenerationHelper.kt. Quando apri questo file, noterai una variabile nella parte superiore della classe chiamata imageGenerator. Questo è l'oggetto Task che svolgerà il lavoro più pesante nella tua app di generazione di immagini.
Appena sotto questo oggetto vedrai una funzione chiamata initializeImageGenerator() con il seguente commento: // Step 2 - inizializza il generatore di immagini. Come puoi immaginare, qui inizializzerai l'oggetto ImageGenerator. Sostituisci il corpo della funzione con il seguente codice per impostare il percorso del modello di generazione di immagini e inizializzare l'oggetto ImageGenerator:
// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Sotto vedrai un'altra funzione denominata setInput(). Questa accetta tre parametri: una stringa prompt che verrà utilizzata per definire l'immagine generata, il numero di iterazioni che l'attività deve eseguire durante la generazione della nuova immagine e un valore seed che può essere utilizzato per creare nuove versioni di un'immagine basate sullo stesso prompt durante la generazione della stessa immagine quando viene utilizzato lo stesso seed. Lo scopo di questa funzione è impostare questi parametri iniziali per il generatore di immagini quando tenti di creare un'immagine che mostra i passaggi intermedi.
Procedi e sostituisci il corpo di setInput() (dove vedrai il commento // Step 3 - accept inputs) con questa riga:
// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)
I due passaggi successivi sono quelli in cui avviene la generazione. La funzione generate() accetta gli stessi input di setInput, ma crea un'immagine come chiamata one-shot che non restituisce immagini di passaggi intermedi. Puoi sostituire il corpo di questa funzione (che include il commento // Step 4 - generate without showing iterations) con il seguente:
// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
È importante sapere che questa attività viene eseguita in modo sincrono, quindi dovrai chiamare la funzione da un thread in background. Scoprirai di più su questo argomento più avanti in questo codelab.
L'ultimo passaggio che devi eseguire in questo file è compilare la funzione execute() (etichettata come passaggio 5). Questo accetterà un parametro che indica se deve restituire o meno un'immagine intermedia per il singolo passaggio di generazione che verrà eseguito con la funzione execute() di ImageGenerator. Sostituisci il corpo della funzione con questo codice:
// Step 5 - generate with iterations
val result = imageGenerator.execute(showResult)
if (result == null || result.generatedImage() == null) {
return Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888)
.apply {
val canvas = Canvas(this)
val paint = Paint()
paint.color = Color.WHITE
canvas.drawPaint(paint)
}
}
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
Questo è tutto per il file di assistenza. Nella sezione successiva compilerai il file ViewModel che gestisce la logica di questo esempio.
4. Unire l'app
Il file MainViewModel gestirà gli stati dell'interfaccia utente e altre logiche relative a questa app di esempio. Aprilo ora.
Verso l'inizio del file dovresti vedere il commento // Step 6 - set model path. Qui indicherai alla tua app dove trovare i file del modello necessari per la generazione di immagini. Per questo esempio, imposta il valore su /data/local/tmp/image_generator/bins/.
// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"
Da qui, scorri verso il basso fino alla funzione generateImage(). Verso la parte inferiore di questa funzione vedrai i passaggi 7 e 8, che verranno utilizzati per generare immagini con le iterazioni restituite o nessuna, rispettivamente. Poiché entrambe le operazioni vengono eseguite in modo sincrono, noterai che sono racchiuse in una coroutine. Puoi iniziare sostituendo // Step 7 - Generate without showing iterations con questo blocco di codice per chiamare generate() dal file ImageGenerationHelper, quindi aggiorna lo stato dell'interfaccia utente.
// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
it.copy(outputBitmap = result)
}
Il passaggio 8 è un po' più complicato. Poiché la funzione execute() esegue solo un passaggio anziché tutti i passaggi per la generazione di immagini, dovrai chiamare ogni passaggio singolarmente tramite un ciclo. Dovrai anche determinare se il passaggio corrente deve essere visualizzato per l'utente. Infine, aggiornerai lo stato della UI se deve essere visualizzata l'iterazione corrente. Ora puoi fare tutto questo.
// Step 8 - Generate with showing iterations
helper?.setInput(prompt, iteration, seed)
for (step in 0 until iteration) {
isDisplayStep =
(displayIteration > 0 && ((step + 1) % displayIteration == 0))
val result = helper?.execute(isDisplayStep)
if (isDisplayStep) {
_uiState.update {
it.copy(
outputBitmap = result,
generatingMessage = "Generating... (${step + 1}/$iteration)",
)
}
}
}
A questo punto dovresti essere in grado di installare la tua app, inizializzare il generatore di immagini e quindi creare una nuova immagine basata su un prompt di testo
… tranne che ora l'app va in crash quando provi a inizializzare il generatore di immagini. Il motivo è che devi copiare i file del modello sul dispositivo. Per ottenere le informazioni più aggiornate sui modelli di terze parti noti per funzionare, convertirli per questa attività MediaPipe e copiarli sul tuo dispositivo, puoi consultare questa sezione della documentazione ufficiale.
Oltre a copiare i file direttamente sul dispositivo di sviluppo, è anche possibile configurare Firebase Storage per scaricare i file necessari direttamente sul dispositivo dell'utente in fase di runtime.
5. Esegui il deployment e testa l'app
Dopo tutto questo, dovresti avere un'app funzionante in grado di accettare un prompt di testo e generare nuove immagini interamente sul dispositivo. Procedi con l'implementazione dell'app su un dispositivo Android fisico per testarla, ma ricorda che dovrai provare questa operazione con un dispositivo con almeno 8 GB di memoria.
- Fai clic su Esegui (
) nella barra degli strumenti di Android Studio per eseguire l'app. - Seleziona il tipo di passaggi di generazione (finali o con iterazioni) e poi premi il pulsante INIZIALIZZA.
- Nella schermata successiva, imposta le proprietà che preferisci e fai clic sul pulsante GENERA per vedere cosa propone lo strumento.

6. Complimenti!
Ce l'hai fatta! In questo codelab hai imparato ad aggiungere la generazione da testo a immagine on-device a un'app per Android.
Passaggi successivi
Puoi fare molto di più con l'attività di generazione di immagini, ad esempio:
- utilizzando un'immagine di base per strutturare le immagini generate tramite plug-in o addestrando i tuoi pesi LoRA aggiuntivi tramite Vertex AI.
- Utilizza Firebase Storage per recuperare i file del modello sul tuo dispositivo senza richiedere l'utilizzo dello strumento ADB.
Non vediamo l'ora di vedere tutte le cose interessanti che realizzerai con questa attività sperimentale. Continua a seguirci per non perderti altri codelab e contenuti del team MediaPipe.