1. Introduction
Qu'est-ce que MediaPipe ?
MediaPipe Solutions vous permet d'appliquer des solutions de machine learning (ML) à vos applications. Vous accédez à un framework avec lequel vous pouvez configurer des pipelines de traitement prédéfinis qui fournissent aux utilisateurs une sortie immédiate, attrayante et utile. Vous pouvez même personnaliser de nombreuses solutions avec MediaPipe Model Maker afin de modifier les modèles par défaut.
La génération de texte en image est l'une des nombreuses tâches de ML proposées par MediaPipe Solutions.
Dans cet atelier de programmation, vous allez commencer par une application Android presque vide, puis suivre plusieurs étapes jusqu'à ce que vous puissiez générer de nouvelles images directement sur votre appareil Android.
Points abordés
- Implémenter la génération de texte en image en local dans une application Android avec MediaPipe Tasks
Ce dont vous avez besoin
- Une version installée d'Android Studio (cet atelier de programmation a été écrit et testé avec Android Studio Giraffe).
- Un appareil Android doté d'au moins 8 Go de RAM.
- Des connaissances de base sur le développement Android et la possibilité d'exécuter un script Python prédéfini.
2. Ajouter MediaPipe Tasks à l'application Android
Télécharger l'application de démarrage Android
Cet atelier de programmation commencera par un exemple prédéfini composé de l'interface utilisateur qui sera utilisée pour une version de base de la génération d'images. Vous trouverez cette application de démarrage dans le dépôt officiel d'exemples MediaPipe ici. Clonez le dépôt ou téléchargez le fichier ZIP en cliquant sur Code > Download ZIP (Code > Télécharger le ZIP).
Importer l'application dans Android Studio
- Ouvrez Android Studio.
- Sur l'écran Welcome to Android Studio (Bienvenue dans Android Studio), sélectionnez Open (Ouvrir) en haut à droite.

- Accédez à l'endroit où vous avez cloné ou téléchargé le dépôt, puis ouvrez le répertoire codelabs/image_generation_basic/android/start.
- À ce stade, l'application ne doit pas être compilée , car vous n'avez pas encore inclus la dépendance MediaPipe Tasks.
Pour corriger l'application et la faire fonctionner, accédez au fichier build.gradle et faites défiler la page jusqu'à // Step 1 - Add dependency. À partir de là, incluez la ligne suivante, puis cliquez sur le bouton Sync Now (Synchroniser) qui s'affiche dans la bannière en haut d'Android Studio.
// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
Une fois la synchronisation terminée, vérifiez que tout s'est ouvert et installé correctement en cliquant sur la flèche verte run (
) en haut à droite d'Android Studio. L'application devrait s'ouvrir sur un écran avec deux boutons radio et un bouton libellé INITIALIZE (INITIALISER). Si vous cliquez sur ce bouton, vous devriez être immédiatement redirigé vers une interface utilisateur distincte composée d'une requête textuelle et d'autres options, ainsi que d'un bouton libellé GENERATE (GÉNÉRER).

Malheureusement, c'est à peu près tout ce que l'application de démarrage peut faire. Il est donc temps d'apprendre à terminer cette application et à commencer à générer de nouvelles images sur votre appareil.
3. Configurer le générateur d'images
Dans cet exemple, la majeure partie du travail de génération d'images aura lieu dans le fichier ImageGenerationHelper.kt. Lorsque vous ouvrez ce fichier, vous remarquez une variable en haut de la classe appelée imageGenerator. Il s'agit de l'objet Task qui effectuera le gros du travail dans votre application de génération d'images.
Juste en dessous de cet objet, vous verrez une fonction appelée initializeImageGenerator() avec le commentaire suivant : // Step 2 - initialize the image generator. Comme vous pouvez l'imaginer, c'est là que vous allez initialiser l'objet ImageGenerator. Remplacez le corps de cette fonction par le code suivant pour définir le chemin d'accès au modèle de génération d'images et initialiser l'objet ImageGenerator :
// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
Vous verrez ensuite une autre fonction nommée setInput(). Elle accepte trois paramètres : une chaîne prompt qui sera utilisée pour définir l'image générée, le nombre d'iterations que la tâche doit effectuer lors de la génération de la nouvelle image et une valeur seed qui peut être utilisée pour créer de nouvelles versions d'une image basée sur la même requête tout en générant la même image lorsque la même valeur initiale est utilisée. L'objectif de cette fonction est de définir ces paramètres initiaux pour le générateur d'images lorsque vous tentez de créer une image qui affiche des étapes intermédiaires.
Remplacez le corps de setInput() (où vous verrez le commentaire // Step 3 - accept inputs) par cette ligne :
// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)
Les deux étapes suivantes sont celles où la génération a lieu. La fonction generate() accepte les mêmes entrées que setInput, mais crée une image en un seul appel qui ne renvoie aucune image d'étape intermédiaire. Vous pouvez remplacer le corps de cette fonction (qui inclut le commentaire // Step 4 - generate without showing iterations) par le code suivant :
// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
Il est important de savoir que cette tâche s'effectue de manière synchrone. Vous devrez donc appeler la fonction à partir d'un thread d'arrière-plan. Vous en apprendrez davantage un peu plus loin dans cet atelier de programmation.
La dernière étape que vous allez effectuer dans ce fichier consiste à remplir la fonction execute() (intitulée Step 5). Elle acceptera un paramètre qui lui indique si elle doit renvoyer ou non une image intermédiaire pour l'étape unique de génération qui sera effectuée avec la fonction ImageGenerator execute(). Remplacez le corps de la fonction par le code suivant :
// 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
Et voilà pour le fichier d'assistance. Dans la section suivante, vous allez remplir le fichier ViewModel qui gère la logique de cet exemple.
4. Assembler l'application
Le fichier MainViewModel gérera les états de l'interface utilisateur et d'autres logiques liées à cette application exemple. Ouvrez-le maintenant.
En haut du fichier, vous devriez voir le commentaire // Step 6 - set model path. C'est là que vous indiquerez à votre application où trouver les fichiers de modèle nécessaires à la génération d'images. Pour cet exemple, vous allez définir la valeur sur /data/local/tmp/image_generator/bins/.
// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"
Faites ensuite défiler la page jusqu'à la fonction generateImage(). En bas de cette fonction, vous verrez les étapes 7 et 8, qui seront utilisées pour générer des images avec ou sans itérations renvoyées, respectivement. Comme ces deux opérations se produisent de manière synchrone, vous remarquerez qu'elles sont encapsulées dans une coroutine. Vous pouvez commencer par remplacer // Step 7 - Generate without showing iterations par ce bloc de code pour appeler generate() à partir du fichier ImageGenerationHelper, puis mettre à jour l'état de l'interface utilisateur.
// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
it.copy(outputBitmap = result)
}
L'étape 8 est un peu plus délicate. Étant donné que la fonction execute() n'effectue qu'une étape au lieu de toutes les étapes de génération d'images, vous devrez appeler chaque étape individuellement via une boucle. Vous devrez également déterminer si l'étape actuelle doit être affichée pour l'utilisateur. Enfin, vous mettrez à jour l'état de l'interface utilisateur si l'itération actuelle doit être affichée. Vous pouvez le faire maintenant.
// 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)",
)
}
}
}
À ce stade, vous devriez pouvoir installer votre application, initialiser le générateur d'images, puis créer une image basée sur une requête textuelle.
... sauf que l'application plante lorsque vous essayez d'initialiser le générateur d'images. Cela est dû au fait que vous devez copier vos fichiers de modèle sur votre appareil. Pour obtenir les informations les plus récentes sur les modèles tiers connus pour fonctionner, les convertir pour cette tâche MediaPipe et les copier sur votre appareil, vous pouvez consulter cette section de la documentation officielle.
En plus de copier des fichiers directement sur votre appareil de développement, vous pouvez également configurer Firebase Storage pour télécharger les fichiers nécessaires directement sur l'appareil de l'utilisateur au moment de l'exécution.
5. Déployer et tester l'application
Après tout cela, vous devriez disposer d'une application fonctionnelle capable d'accepter une requête textuelle et de générer de nouvelles images entièrement sur l'appareil. Déployez l'application sur un appareil Android physique pour la tester. N'oubliez pas que vous devez essayer avec un appareil doté d'au moins 8 Go de mémoire.
- Cliquez sur Run (
) dans la barre d'outils Android Studio pour exécuter l'application. - Sélectionnez le type d'étapes de génération (final ou avec itérations), puis appuyez sur le bouton INITIALIZE (INITIALISER).
- Sur l'écran suivant, définissez les propriétés de votre choix, puis cliquez sur le bouton GENERATE (GÉNÉRER) pour voir ce que l'outil propose.

6. Félicitations !
Bravo ! Dans cet atelier de programmation, vous avez appris à ajouter la génération de texte en image sur l'appareil à une application Android.
Étapes suivantes
Vous pouvez faire plus avec la tâche de génération d'images, y compris :
- utiliser une image de base pour structurer les images générées via des plug-ins ou entraîner vos propres pondérations LoRA supplémentaires via Vertex AI ;
- utiliser Firebase Storage pour récupérer les fichiers de modèle sur votre appareil sans avoir à utiliser l'outil ADB.
Nous avons hâte de découvrir toutes les choses intéressantes que vous allez créer avec cette tâche expérimentale. Restez à l'écoute pour découvrir d'autres ateliers de programmation et contenus de l'équipe MediaPipe !