【问题标题】:Best quality image allocation from resources based on resolution/density基于分辨率/密度的资源的最佳质量图像分配
【发布时间】:2014-05-08 05:10:17
【问题描述】:

我正在为 Android“多屏幕尺寸”领域中的一项非常琐碎的任务而苦苦挣扎。

我正在努力实现的目标

与屏幕宽度匹配的布局,具有可调整大小的九个补丁背景(仅水平方向,因为始终有足够的垂直空间)。这是一个虚拟图像:

我的目标是,根据屏幕分辨率,通过使用一组不同的尺寸,例如以最高分辨率显示图像。 320x45、480x67、600x87、720x101,没有任何缩小。 我希望有一个非程序化的解决方案。

上面提到的图像大小的一个例子是:

  • 3.7" Nexus One (480 x 800) - 480x67 图像看起来最好。
  • 4.7" Galaxy Nexus (720 x 1280) - 720x101 图片。
  • 4.7" Nexus 4 (768 x 1280) - 还是 720x101 的图像,拉伸到完整的 768 像素宽度并变为 768x101。

问题

整个 Android 资源分配围绕dps(与密度无关的像素)展开,而实际上我想根据实际可用像素显示图像。

如果我将 480x67 图像分配给 res/drawable-mdpi 并将 600x87 图像分配给 res/drawable-hdpi,那么图像将在 5.4" display of 480x800 上正确显示,即 mdpi 显示。但是,4" 480x800 显示器符合 hdpi 标准,系统将指定 600x87 image, which won't fit the screen

我按照in the online guide 的描述尝试了smallestWidth 参数,但这会产生奇怪的结果。例如,一个 3.7" 480 x 800 显示器 (hdpi) 使用我的 drawable-sw320dp 图像,尽管也有一个 drawable-sw480dp 资源可用。

分配具有最佳质量的可拉伸、宽度匹配的图像的最佳方法是什么?没有非程序化的解决方案吗?

提前致谢!

【问题讨论】:

  • 我认为第一个错误是尝试做你想做的事情,而不是像谷歌建议的那样。 DONT USE PIXEL,你可以用 dp、sp 做任何事情,而且是正确的方法。

标签: android nine-patch xml-drawable


【解决方案1】:

我相信,通过结合密度和屏幕尺寸资源限定符,您可以实现接近最佳的行为。

让我们假设这种资源文件夹结构:

  • drawable-normal-hdpi - A normal 尺寸指示最小宽度 320dp。 hdpi 规定 1.5X dp 到像素乘数。所以最小 px normal hdpi 桶的宽度为 480px。我们在这里放了一个 480px 宽的 图片。
  • drawable-normal-xhdpi - 尺寸再次规定为 320dp,但这次 与 2X 乘数。所以我们使用 640 像素宽的图片。
  • drawable-xlarge-mdpi - 大小意味着至少 720dp。 mdpi 乘数 是 1X,所以我们使用 720 像素宽的图片。

现在让我们看看一些设备,看看它们是如何落入这些桶的:

  • Nexus 1 - normal hdpi。实际像素宽度:480 像素。图片很合适 完美。
  • 银河系 - normal xhdpi。我们可以适应 720px 的图像,所以 我们使用的 640 像素图片不是最佳的 - 但非常接近。
  • Nexus 4 就像 Gnex。
  • Nexus 10.1 (1280X800) - xlarge mdpi。我们可以容纳 800px,我们的图像 是 720 像素。同样不理想,但足够接近。

最坏的情况:使用的图像质量可能提高 5-10%。 最佳案例:完美契合。

此方法的主要缺点是您需要提供大量资源和文件夹来解决大小和密度的所有排列(如果您需要将其与更多的语言环境、方向等限定符结合起来,那就更糟了)在)。但是,就我对 Android 的理解而言,我认为如果不编码,您无法实现比这更好的目标。


关于smallestWidth 的评论:您的怪异行为示例实际上是预期的行为。 hdpi 乘数是 1.5 - 所以 480px 宽的 hdpi 显示器正好是 320dp 宽。如文档所述,这使得 drawable-sw320dp 成为正确的选择。我不确定您是否可以将 smallestWidth 限定符与 dpi 限定符结合使用。如果可能的话,您可能会得到比尺寸修饰符更准确的结果。但这意味着图像质量提高 5% 需要更多的排列组合。可能不值得。

【讨论】:

  • 一个很好的答案,非常感谢! the minimum px width of the normal hdpi bucket is 480px - 我不知道,有官方参考吗?另外,我有一个担心 - 可能会有一个显示,比如说 - 1.75" 上的 320x480。因为这是一个 xhdpi 显示 - 640px 宽的图像不适合。
  • developer.android.com/guide/practices/screens_support.html 在 DP 中为每个屏幕尺寸指定了保证的最小尺寸,因此对于每个尺寸+dpi 组合,您可以确定最小 px 尺寸。这也解决了您的问题 - 小屏幕必须至少为 320dp 宽。像这样的屏幕必须归类为 mdpi 以适应官方文档。但是我怀疑,如果我们确实开始看到这样的屏幕(可能与 Android Wear 一起使用......),一些存储桶和定义将不得不改变。对于这么小的屏幕,它们没有多大意义。
【解决方案2】:

实际上,您的方法不是应有的方式。我将为您推荐 2 种方法,一种很简单,但以编程方式进行,另一种是使用自定义视图。

方法 1 - 以编程方式

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int screenWidth = displaymetrics.widthPixels; 
    // this will determine "scale ratio" so using which image height and width won't matter 
    int imageOriginalHeight = 101; // your original image height        
    int imageOriginalWidth = 720; // your original image width
    int imageScaleHeight = (screenWidth*imageOriginalHeight) / imageOriginalWidth;

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, imageScaleHeight);
    imageView.setLayoutParams(params);
    imageView.setImageResource(R.drawable.file);

方法 2 - 自定义视图

您可以使用由 Maurycy Wojtowicz 编写的名为 ScaleImageView 的自定义视图。

类定义如下:

此视图将通过确定是否自动确定宽度或高度 设置高度或宽度(精确大小或 match_parent)并缩放 其他尺寸取决于图像尺寸 此视图也 包含一个调用 changed(boolean isEmpty) 的 ImageChangeListener 一旦对 ImageView 进行了更改

这就是你将如何实现它。

创建一个名为 ScaleImageView.java 的类并复制上面链接的内容。

在你的xml文件中,创建一个ScaleImageView,就像ImageView一样(我在下面写的例子是填充屏幕宽度,并据此缩放高度,因此左右两侧不会有空格)

    <com.project.customview.ScaleImageView
        android:id="@+id/scaleImageView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/file" />

如果你需要在你的Activity中以编程方式声明和设置,也和使用ImageView一样:

imageView = (ScaleImageView)findViewById(R.id.scaleImageView);
imageView.setImageResource(R.drawable.file);

【讨论】:

  • 我希望在通用 Android 框架中采用非编程方式。不得不再次重新计算资源分配很痛苦。
  • 然后使用第二种方法:) 支持多个屏幕需要这样的功能,至少据我所知。但我总是尝试使用第一种方法,因为它是最稳定的一种。
【解决方案3】:

在 android 中,您可以选择 hdpi、mdpi、xdpi 等。

文件夹,您必须根据您的设备分辨率创建不同的图像,并在确认您的设备分辨率和密度类别后将您的图像放在那里。

更多参考为什么会发生,你可以在这里看到

我在这里解释一些图表可能对你有帮助。

低密度小屏幕 QVGA 240x320 (120dpi):

drawable-small-ldpi (240x320)
可绘制的小土地 ldpi (320x240)

低密度普通屏幕 WVGA400 240x400 (x432) (120dpi):

drawable-ldpi (240 x 400 ) 可绘制土地 ldpi (400 x 240 )

中密度普通屏幕 HVGA 320x480 (160dpi):

drawable-mdpi (320 x 480 ) 可绘制土地 mdpi (480 x 320 )

中密度大屏幕 HVGA 320x480 (160dpi):

drawable-large-mdpi (320 x 480 ) 可绘制大地 mdpi (480 x 320)

Galaxy Tab(240 dpi):

drawable-large (600 x 1024) 可绘制大地 (1024 x 600)

高密度普通屏幕 WVGA800 480x800 (x854) (240 dpi):

drawable-hdpi (480 x 800) drawable-land-hdpi (800 x 480)

Xoom(中密度大,但分辨率为 1280x800 分辨率)(160 dpi):

drawable-xlarge (800 x 1280) drawable-xlarge-land (1280 x 800)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 2012-10-27
    • 2019-07-25
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多