1. 简介
什么是 MediaPipe?
借助 MediaPipe 解决方案,您可以将机器学习 (ML) 解决方案应用于您的应用。它提供了一个框架,可让您配置预构建的处理流水线,用于为用户提供即时的、有吸引力的有用输出。您甚至可以使用 MediaPipe Model Maker 自定义其中许多解决方案,以更新默认模型。
文本转图像生成是 MediaPipe Solutions 提供的多项机器学习任务之一。
在此 Codelab 中,您将从一个几乎空白的 Android 应用入手,然后完成多个步骤,直到能够直接在 Android 设备上生成新图片。
学习内容
- 如何使用 MediaPipe Tasks 在 Android 应用中本地运行文本转图片生成功能。
所需条件
- 安装好的 Android Studio 版本(此 Codelab 是使用 Android Studio Giraffe 编写和测试的)。
- 一部 RAM 至少为 8GB 的 Android 设备。
- 具备 Android 开发基础知识,并且能够运行预先编写的 Python 脚本。
2. 向 Android 应用添加 MediaPipe 任务
下载 Android 起始应用
本 Codelab 将从一个预先创建的示例开始,其中包含用于基本版本图片生成的界面。您可以在官方 MediaPipe 示例代码库的此处找到该启动应用。点击“Code”(代码)>“Download ZIP”(下载 ZIP 文件),克隆代码库或下载 ZIP 文件。
将应用导入 Android Studio
- 打开 Android Studio。
- 在 Welcome to Android Studio 屏幕中,选择右上角的 Open。
- 前往您克隆或下载代码库的位置,然后打开 codelabs/image_generation_basic/android/start 目录。
- 在此阶段,应用不应编译,因为您尚未添加 MediaPipe Tasks 依赖项。
您需要进入 build.gradle 文件,然后向下滚动到 // Step 1 - Add dependency,以修复应用并使其运行。然后,添加以下代码行,然后点击 Android Studio 顶部横幅中显示的 Sync Now 按钮。
// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
同步完成后,点击 Android Studio 右上角的绿色运行箭头 ( ),验证所有内容是否已正确打开和安装。您应该会看到应用打开到一个屏幕,其中包含两个单选按钮和一个标签为 INITIALIZE 的按钮。如果您点击该按钮,系统应该会立即将您转到一个单独的界面,其中包含文本提示、其他选项以及标记为 GENERATE(生成)的按钮。
很遗憾,这大概就是此入门应用的全部内容了,接下来,您需要了解如何完成此应用并开始在设备上生成新图片!
3. 设置图片生成器
在此示例中,大部分图片生成工作将在 ImageGenerationHelper.kt 文件中完成。打开此文件后,您会在类顶部看到一个名为 imageGenerator 的变量。这是在图片生成应用中执行繁重工作任务的 Task 对象。
在该对象下方,您会看到一个名为 initializeImageGenerator() 的函数,其中包含以下注释:// Step 2 - initialize the image generator. 正如您可能猜到的那样,您将在此处初始化 ImageGenerator 对象。将该函数正文替换为以下代码,以设置图片生成模型路径并初始化 ImageGenerator 对象:
// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
在该代码下方,您会看到另一个名为 setInput() 的函数。该函数接受三个参数:用于定义生成的图片的提示字符串、任务在生成新图片时应完成的迭代次数,以及一个种子值,该值可用于根据同一提示创建图片的新版本,同时在使用相同种子时生成相同的图片。此函数的用途是在您尝试创建会显示中间步骤的图片时,为图片生成器设置这些初始参数。
继续将 setInput() 正文(您会看到注释“// Step 3 - accept inputs”)替换为以下代码行:
// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)
接下来的两个步骤是生成过程。generate() 函数接受与 setInput 相同的输入,但会以一次性调用的形式创建图片,而不会返回任何中间步骤图片。您可以将此函数的正文(包括注释“// Step 4 - generate without showing iterations”)替换为以下代码:
// 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 步,它们分别用于生成包含返回的迭代次数或不含任何迭代次数的图片。由于这两项操作都是同步进行的,因此您会发现它们都封装在协程中。首先,您可以将“// Step 7 - Generate without showing iterations”替换为以下代码块,以便从 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 Storage,以便在运行时将必要的文件直接下载到用户的设备。
5. 部署和测试应用
完成所有这些操作后,您应该会得到一个可以接受文本提示并完全在设备端生成新图片的应用!接下来,将应用部署到实体 Android 设备进行测试,但请注意,您需要使用内存至少为 8GB 的设备进行测试。
- 点击 Android Studio 工具栏中的“Run”(运行)图标 (
) 以运行应用。
- 选择生成步骤的类型(最终步骤或迭代步骤),然后按 INITIALIZE 按钮。
- 在下一个屏幕上,设置您需要的任何属性,然后点击生成按钮,查看该工具生成的内容。
6. 恭喜!
大功告成!在本 Codelab 中,您学习了如何向 Android 应用添加设备端文本转图片生成功能。
后续步骤
您还可以使用图片生成任务执行更多操作,包括:
- 使用基础图片通过插件构建生成的图片,或通过 Vertex AI 训练您自己的其他 LoRA 权重。
- 使用 Firebase Storage 检索设备上的模型文件,而无需使用 ADB 工具。
我们期待看到您通过此实验性任务制作的所有精彩内容,并敬请关注 MediaPipe 团队提供的更多 Codelab 和内容!