1. 简介
什么是 MediaPipe?
借助 MediaPipe 解决方案,您可以将机器学习 (ML) 解决方案应用于自己的应用。它提供了一个框架,用于配置预构建的处理流水线,以便为用户提供即时、富有吸引力的实用输出。您甚至可以使用 MediaPipe Model Maker 自定义其中许多解决方案来更新默认模型。
文本到图像生成是 MediaPipe 解决方案提供的若干机器学习任务之一。
在此 Codelab 中,您将从一个基本上为裸体的 Android 应用开始,然后执行多个步骤,直到能够直接在 Android 设备上生成新图片。
学习内容
- 如何使用 MediaPipe Tasks 在 Android 应用中实现在本地运行的文本转图像生成功能。
所需条件
- 已安装版本的 Android Studio(此 Codelab 是使用 Android Studio Giraffe 编写和测试的)。
- RAM 至少为 8GB 的 Android 设备。
- 具备 Android 开发方面的基础知识,能够运行预先编写的 Python 脚本。
2. 将 MediaPipe Tasks 添加到 Android 应用
下载 Android 起始应用
此 Codelab 将从一个预制示例入手,该示例包含用于生成基本版图片的界面。您可以点击此处,在官方 MediaPipe 示例代码库中找到启动应用。克隆代码库或依次点击“代码”>“下载”以下载 ZIP 文件下载 ZIP 文件。
将应用导入 Android Studio
- 打开 Android Studio。
- 在 Welcome to Android Studio 屏幕中,选择右上角的 Open。
- 转到您克隆或下载代码库的位置,然后打开 codelabs/image_generation_basic/android/start 目录。
- 在此阶段,应用不应编译,因为您尚未添加 MediaPipe Tasks 依赖项。
您将进入 build.gradle 文件并向下滚动到// 第 1 步 - 添加依赖项,以修复应用并使其运行。在其中添加以下代码行,然后点击 Android Studio 顶部横幅中显示的 Sync Now 按钮。
// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
同步完成后,点击 Android Studio 右上角的绿色 run 箭头 ( ),验证所有内容是否正确打开和安装。您应该会看到该应用打开一个屏幕,其中有两个单选按钮和一个标签为 INITIALIZE 的按钮。如果您点击该按钮,系统应该会立即为您打开另一个界面,其中包括文本提示和其他选项,旁边还有一个标记为生成的按钮。
很遗憾,这只是起始应用的范围,因此现在您将了解如何完成该应用,并开始在设备上生成新图片!
3. 设置图片生成器
在此示例中,大部分图片生成工作都将在 ImageGenerationHelper.kt 文件中进行。当您打开此文件时,您会在该类的顶部看到一个名为 imageGenerator 的变量。这是将在您的图片生成应用中完成繁重工作的 Task 对象。
在该对象正下方,您会看到一个名为 initializeImageGenerator() 的函数,其注释如下:// 第 2 步 - 初始化图片生成器。您可能已经猜到,您可以在此处初始化 ImageGenerator 对象。将该函数正文替换为以下代码,以设置图片生成模型路径并初始化 ImageGenerator 对象:
// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
在下方,您会看到另一个名为 setInput() 的函数。此方法接受三个参数:提示字符串(用于定义生成的图片)、任务在生成新图片时应执行的迭代次数,以及种子值(用于在使用相同种子时根据相同的提示创建图片的新版本,同时生成相同图片)。此函数的用途是在您尝试创建显示中间步骤的图片时,为图片生成器设置这些初始参数。
接下来,使用以下代码行替换 setInput() 正文(您会在其中看到注释 // 第 3 步 - 接受输入 ):
// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)
接下来的两个步骤是生成过程。generate() 函数接受与 setInput 相同的输入,但以单次调用的形式创建图片,且不返回任何中间步骤图片。您可以将此函数的正文(包含注释 // Step 4 - generate without; generate extensions )替换为以下内容:
// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
请务必了解,此任务是同步发生的,因此您需要从后台线程调用函数。此 Codelab 稍后会对此进行详细介绍。
在此文件中,最后一步是填写 execute() 函数(标记为第 5 步)。此方法将接受一个参数,用于告知它是否应针对将通过 ImageGenerator execute() 函数执行的单步生成步骤返回中间图片。将函数正文替换为以下代码:
// 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
有关帮助程序文件的介绍到此结束在下一部分中,您将填写用于处理此示例逻辑的 ViewModel 文件。
4. 整合应用
MainViewModel 文件将处理与此示例应用相关的界面状态和其他逻辑。请立即打开该文件。
在文件顶部,您应该会看到注释 // Step 6 - set model path.您将在此处指示应用可在什么位置找到生成图片所需的模型文件。在此示例中,您将将该值设置为 /data/local/tmp/image_generator/bins/。
// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"
在这里,向下滚动到 generateImage() 函数。在此函数的底部,您会看到第 7 步和第 8 步,它们将分别用于生成包含返回迭代或没有迭代的图像。由于这两项操作是同步发生的,您会注意到它们封装在协程中。您可以先将 // 第 7 步 - 生成,但不显示迭代,将此代码块替换为从 ImageGenerationHelper 文件中调用 generate(),然后更新界面状态。
// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
it.copy(outputBitmap = result)
}
第 8 步有点复杂。对于图片生成,由于 execute() 函数仅执行一个步骤(而非所有步骤),因此您需要通过循环来单独调用每个步骤。您还需要确定是否应向用户显示当前步骤。最后,如果应显示当前迭代,您将更新界面状态。您现在可以执行所有这些操作。
// 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)",
)
}
}
}
此时,您应该能够安装您的应用,初始化图片生成器,然后根据文本提示创建新图片
...不过现在,当您尝试初始化图片生成器时,应用会崩溃。出现这种情况的原因是,您需要将模型文件复制到设备。如需获取有关已知有效第三方模型的最新信息、针对此 MediaPipe 任务转换模型并将它们复制到您的设备,您可以查看官方文档的此部分。
除了将文件直接复制到开发设备之外,还可以将 Firebase 存储设置为在运行时将必要的文件直接下载到用户的设备上。
5. 部署并测试应用
完成上述所有操作后,您应该会得到一个可正常运行的应用,能够接受文本提示并完全在设备端生成新图像!接下来将应用部署到实体 Android 设备以对其进行测试,不过请记住,您必须使用至少 8GB 内存的设备尝试此操作。
- 点击 Android Studio 工具栏中的“Run”(
) 以运行该应用。
- 选择生成步骤的类型(最终步骤或迭代步骤),然后按 INITIALIZE 按钮。
- 在下一个屏幕上,根据需要设置任何属性,然后点击生成按钮,查看该工具生成的结果。
6. 恭喜!
大功告成!在此 Codelab 中,您学习了如何为 Android 应用添加设备端文本到图像生成功能。
后续步骤
您还可以完成图片生成任务的其他操作,包括
- 通过插件使用基础图片构建生成的图片,或通过 Vertex AI 训练您自己的其他 LoRA 权重。
- 您可以使用 Firebase 存储在设备上检索模型文件,而无需使用 ADB 工具。
我们期待看到你通过此实验任务创造出的所有酷炫成果,也敬请关注更多来自 MediaPipe 团队的 Codelab 和内容!