在 App Inventor 2 中使用图像

« 返回首页

在 App Inventor 2 中使用图像,避免一些常见的陷阱!

  1. 内存不足错误

  2. 误用大图像的示例

  3. 使用”恰到好处”大小的图像

  4. 选择”恰到好处”的大小

  5. 确定图像在屏幕上的大小

  6. 固定尺寸与响应式尺寸的详细信息

  7. 总结:MIT App Inventor 程序员应该做什么

概要: 如果您使用与屏幕上显示大小相匹配的图像,App Inventor 效果最佳。如果您将较大的图像导入到应用程序中,您的应用程序可能会耗尽系统内存。

1. 内存不足错误

在 App Inventor 中构建应用程序的人可能会发现,当他们尝试运行应用程序时,应用程序会崩溃[a],并出现类似以下错误消息:

Failed to allocate a 25165836 byte allocation with 3395432 free bytes and 3MB until OOM

这里发生的情况是应用程序内存不足(OOM)。在上述消息的情况下,手机试图分配 25 兆字节(25165836 字节),但只有 3 兆字节(3395432 字节)可用。尝试分配如此大量内存的最常见原因是手机试图显示一个巨大的图像,通常是一个比应用程序所需大得多的图像。

每个图像都有一个基于其宽度和高度的”大小”(以像素为单位)。您可以将这两个数字相乘,以了解显示图像所需的内存量。

App Inventor 允许您获取图像(例如从网络)并将这些图像作为媒体导入到您的应用程序中。当您使用这些图像时,App Inventor 会将它们重新缩放以适应应用程序中指定的屏幕区域。有时要显示的图像会比设计的手机区域大。即便如此,即使重新缩放的结果是一个小图像,也需要将大图像保存在内存中才能进行重新缩放。

2. 误用大图像的示例

假设您要显示一个字母表的网格,其中每个字母都在一个 30×30 像素的正方形中。您会期望每个字母占用 30×30 = 900 像素,因此整个网格(假设每个像素 4 字节,这在 Android 中很典型)需要 900×26×4 = 93600 或大约 100 千字节,这将很容易适应手机内存。

另一方面,假设每个字母都是从高分辨率图像加载到应用程序媒体中的,每个图像的大小为 1000 像素 × 1000 像素。每个这样的图像需要 1000×1000 = 100 万像素或 1000×1000×4 = 4 兆字节,整个网格需要 26×4 = 104 兆字节。运行中的应用程序可用的典型内存量范围从 20 到 50 兆字节(更不用说 MIT App Inventor 要求应用程序源文件,包括图像,小于 5 兆字节)。因此应用程序根本无法工作,项目在加载时会收到 OutOfMemory 异常。

即使应用程序可以工作,手机上的结果看起来与使用 30×30 图像的字母几乎没有什么不同。最终,屏幕上的每个图像将是 30×30 像素,即使生成它需要 4 兆字节:大量的空间浪费。

请记住,如果原始图像较大并缩放到 30×30 进行显示,图像仍将根据其实际大尺寸在 Android 设备上消耗内存。

如果您只将图像用作手机上的小图像显示,就没有理由将巨大的图像文件加载到您的应用程序中。

3. 使用”恰到好处”大小的图像

上面字母表示例的总体要点是,您应该尝试使用大小接近它们在设备上实际显示大小的图像。没有理由使用更大的图像:这只会浪费空间。如果您使用较小的图像,App Inventor 会将它们放大以适应屏幕,这可能会降低图像质量。

规则:调整图像大小,使其不要太大也不要太小,而是”恰到好处的大小”。

例如,常见的情况是应用程序违反这一原则使用背景图像,人们下载高分辨率图像(例如 3000×3000 像素)并将其设置为屏幕背景。这只是在浪费空间。最好在将图像上传到应用程序之前,将其调整为更好地匹配设备的屏幕大小。

如果您需要将图像调整为”恰到好处的大小”,可以使用许多工具。工具包括 Photoshop、Preview(在 MacOS 上)、GIMP(在 MacOS、GNU/Linux 和 Windows 上)和 Paint(在 Windows PC 上)。还有更多。有些工具是商业软件,其他工具是免费的或随计算机操作系统提供。您不需要特别花哨的程序(如 Photoshop)来进行图像缩放。甚至可能有一些网站可以上传您的图像,它们会为您重新缩放或压缩图像。在 Google 上搜索”programs for scaling images”或”image compression”可能会找到不少候选方案。然而,压缩并不是需要的;您想要调整到”恰到好处的大小”。

您还可以使用像 Google 图像搜索这样的服务来为您的应用程序找到已经是正确大小的图像,这样您就不需要重新缩放它们。

请记住,图像大小指的是像素的大小(高度和宽度)。您可以使用上述工具之一找到这个。依赖图像的文件大小作为指导并不好,因为大多数图像文件格式都有一定程度的压缩。根据图像类型和实际图像内容,大图像可能会压缩成小文件。对于图形(相对于照片),压缩因子可能特别显著。

4. 首选的图像格式

对于图像来说,最好的图像格式是什么?虽然支持许多格式,但大多数用户使用 JPG(JPEG)或 PNG 图像会获得最佳效果。由于压缩算法的不同,PNG 图像在 Android 设备上通常看起来比 JPG 更清晰,尽管文件大小往往比 JPG 大。(PNG 使用无损压缩;JPG 不使用。)避免使用 BMP 图像;与其他格式相比,BMP 图像非常大,因为它们根本没有压缩。

5. 选择”恰到好处”的大小

当您为应用程序中的使用调整图像大小时,不需要完全匹配它在屏幕上显示的大小。在大多数情况下,将大小调整到近似范围内,让 App Inventor 的自动缩放进行最终调整就足够了。仅依赖自动缩放的一个例外是,如果图像大小远小于屏幕区域大小,那么屏幕上的图像可能会出现低质量。

您可能希望完全避免自动重新缩放,并将图像大小与屏幕区域大小精确匹配。如果您为单个设备设计应用程序,这可能有效。但不同的设备有不同的屏幕大小和不同的屏幕密度(每英寸像素数),因此没有单一的图像大小可以精确匹配所有设备。

原则上,让您的应用程序在所有设备上显示最佳质量的图像,可能需要您提供每个图像的多个副本,大小匹配不同的设备,然后让应用程序在运行时选择适当的图像。这是 Eclipse 和 Android Studio 采用的方法。在设计 App Inventor 时,我们不希望要求我们的开发人员处理这种复杂性。因此,我们建议您根据最关心的设备选择”恰到好处的大小”,并依赖 App Inventor 的自动缩放尽其所能。如果有足够的需求,我们可能会将多图像功能添加到 App Inventor 中。

6. 确定图像在屏幕上的大小

抛开多个设备不谈,屏幕上显示的图像大小将取决于应用程序的设计方式。

在某些情况下,当您使用图像时,图像的大小将用于确定屏幕上对象的大小。例如在 HelloPurr 教程中,您设置一个按钮以图像(在这种情况下是猫)作为其屏幕表示,并将按钮的高度和宽度设置为自动。在这种情况下,图像的大小决定了按钮的大小。

在其他情况下,图像会缩放以适应指定的大小。例如,如果您在屏幕上放置一个图像组件,并将其宽度和高度属性各设置为 100 像素,那么显示的图像将在每个方向上占用 100 像素的屏幕,即使您加载的实际图像大小不同。Android 在显示时会自动缩放图像以适应其容器的大小。请记住,如果原始图像较大并缩放到 100×100 进行显示,图像仍将根据其实际大尺寸在 Android 设备上消耗内存。重复主要规则:如果您只将图像用作应用程序中的小尺寸显示,加载巨大图像只是在浪费空间。

7. 固定尺寸与响应式尺寸的详细信息

本节提供有关 App Inventor 图像缩放的一些背景信息,以及它在不同 App Inventor 版本中的变化情况。

App Inventor 在 2015 年 8 月引入了响应式尺寸。在该版本之前,App Inventor 创建的应用程序标记为 Android API 3(Android 版本 1.45)。这意味着 MIT App Inventor 应用程序在 App Inventor 2 版本 1.45 之前,创建的应用程序可以在旧至 Cupcake(Android 1.5)的手机上运行。但是有一个问题。使用 API 3,Android 仅支持单一设备大小(320 像素宽 × 480 像素高)和单一屏幕密度。

较新的设备通常比这更大,并支持”更密集”的像素(每英寸屏幕空间有更多像素)。不幸的是,当较新的设备加载为 API 3 设计的程序时,Android 会自动缩放屏幕以使其”看起来”像旧设备。这种兼容模式使平板电脑看起来像巨型手机,并简单地放大了 320 x 480 像素的屏幕,这可能使图像(和字体)看起来质量低下。

随着 Android 的发展和 MIT App Inventor 的成熟,AI2 开发人员表达了设计在平板电脑上看起来很好的应用程序的愿望。此外,较新的 Android 设备正在发货时没有 API 3 兼容模式。这使得 MIT App Inventor 应用程序只使用屏幕的一小部分,看起来不正确。

为了支持这些设备,MIT 开发团队需要放弃对 Android 1.5 的支持,并要求至少 Android 1.6(Donut,API 4)。从 API 4 开始,Android 意识到不同的像素密度和屏幕大小。改进的屏幕处理使 Android 应用程序开发比以前更复杂,因为现在应用程序开发人员必须设计他们的应用程序来处理不同的屏幕大小和密度。Google 采取的方法是设计应用程序的几个 UI 版本,包括每个版本的图像文件,并在您的 APK 文件中提供所有图像。然后设备在运行时选择正确的集合。这是 Eclipse 和 Android Studio 编译器中使用的系统。

我们决定,按照 Google Eclipse/Android Studio 模型创建多个 UI 设计,比我们想要让 App Inventor 程序员面对的复杂性更高。我们也不想对 App Inventor 进行更改,要求每个 App Inventor 程序员处理不同大小的设备和多个重复图像。我们确实想要保持我们与 API 3 的兼容模式。然而,这样做需要我们提供我们自己的兼容代码,我们已经这样做了。结果是固定尺寸(试图尽可能模拟原始 API 3 兼容模式)和响应式尺寸。

在 MIT App Inventor 的当前版本中,您可以将 Screen1 上的”Sizing”属性设置为”Responsive”或”Fixed”(”Fixed”是新项目和自动升级的旧项目的默认值)。固定模式试图模拟旧的 API 3 兼容模式行为。模拟并不完全复制旧模式,但我们认为足够接近。响应式模式不调用此兼容功能。使用响应式尺寸的程序员可能需要注意设备之间的差异。为了使为多个屏幕大小编码的机会对 AI2 开发人员尽可能容易,我们引入了一种基于设备屏幕百分比指定屏幕元素宽度和高度的方法,而不是必须给出绝对像素。

此升级带来的另一个变化是”密度无关像素”或”dips”的概念。密度无关像素是一种考虑设备屏幕密度的尺寸度量。在某些设备上,一个 dip 可能映射到一个像素,而在其他设备上可能是九个像素。想法是大多数屏幕每英寸屏幕实际空间将有相同数量的”dips”。

开发人员仍然可以在 App Inventor 中以”像素”给出 UI 元素的大小,但要意识到这些像素实际上是 dips。

图像仍然基于”真实”像素。因此,如果您将 HelloPurr 加载到密度更高的设备上,猫图片将比在 320×480 像素设备上小。为了处理这种差异,App Inventor 在加载图像时根据设备的屏幕密度自动缩放图像。这种自动响应可能导致内存消耗问题。回到上面的字母表示例,如果您尝试将项目加载到屏幕密度为 3 的设备中(并不少见),项目将尝试使用比原始密度 1 示例多 9 倍的内存,或 2.3 千兆字节的内存。因此,即使原始示例在屏幕密度为 1 的设备上适合内存,它肯定不适合屏幕密度为 3 的设备!

8. 总结:MIT App Inventor 程序员应该做什么

简单的解决方案是确保您加载的图像是您最关心的设备的”正确大小”,并让 App Inventor 缩放处理其余部分。回到字母表示例,单个字母的图像应缩放为 30 像素 × 30 像素。如果您将图像调整为 30×30,每个图像将仅需要大约 1000 字节的内存(而不是 10 兆字节!)。整个字母表将适合 26,000 字节的内存。即使您将其加载到屏幕密度为 3 的设备上,它也只消耗大约 200,000 字节的内存。

文档反馈