【问题标题】:Scaling image resources in Android and Picasso在 Android 和 Picasso 中缩放图像资源
【发布时间】:2016-08-26 19:38:00
【问题描述】:

关于密度的资料太多了,multiple screen support,太多了questions on SO,但我还是没有。

我的目标很简单:为ImageView 显示与可用空间一样大的位图。我需要BitMap,因为我会对其进行一些操作。

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/figureView" />

我将在位图中使用一些图片。我会将它们放在drawables 目录中。我将使用R.drawable.pictureX 引用它们。我将使用 Picasso 来加载它们并缩放它们:

Bitmap bitmap = Picasso.with(getContext()).load(resourceId).resize(w, h).get();

对我来说不清楚的部分是所有那些 xxhdpi 文件夹和 Android 启发式选择最好的。

  1. 当文档说 Android 将自动缩放图像时,它是否适用于我的情况?我不想缩放已经缩放的图片。

  2. 我应该在我的机箱中存储多少个 dpi 变体以及存储在哪里?我应该在 no-dpi 文件夹中有单个文件还是应该为每个 dpi 文件夹创建图片变体?

  3. 如何确定图片资源的维度?图标很容易:例如 24x24 dpi,然后使用 DPI 公式将其倍增。但我想覆盖完整的屏幕高度。一章配置示例列出:240x320 ldpi、320x480 mdpi、480x800 hdpi、720x1280 mdpi、800x1280 mdpi 等。资源没有屏幕尺寸限定符。

感谢您的澄清。

【问题讨论】:

    标签: android picasso


    【解决方案1】:

    我意识到实际上很容易找出 Android 行为。我只需要每个 DPI 变体不同,这样我就可以区分它们。我在每张图片中放置了一个带有 DPI 名称和像素分辨率的文本。

    有一个sample GitHub Test DPI project。它有两个ImageViews。第一个是从 XML 初始化的,Android 进行缩放。第二个是我用BitMap 填充的占位符。我输入了 200dp 作为它的大小,这是正确的。 MDPI 的像素大小 = dp 中的大小。

    我的发现是合乎逻辑的。 Android 对我的意图一无所知。它只是为当前 DPI 选择最佳可用资源。

    Nexus 5x 默认使用 XXHDPI,Samsung SIII Mini 使用 HDPI。如果我删除他们的默认 DPI 文件夹,他们会缩小更高的可用变体:XXXHDPI 和 XHDPI。如果我删除除 NODPI 之外的所有变体,就会使用它。

    最后,如果我将从源代码动态加载的 ImageView 的尺寸更改为 300dp,那么它将被缩放并且看起来很丑。 Android 无法在 decodeResource 执行时知道我稍后会对其进行扩展并且有更好的资源可用。

    尚不清楚的是如何找出适合屏幕的图片尺寸。

    Java:

    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inScaled = false;
    Bitmap figureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_test, opt);
    ImageView imageView=(ImageView) findViewById(R.id.testView);
    imageView.setImageBitmap(figureBitmap);
    

    活动:

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_test" />
    <ImageView
        android:id="@+id/testView"
        android:layout_width="200dp"
        android:layout_height="200dp" />
    

    8 月 30 日更新

    原图:230x541 px,正在加载

    Picasso.with(getContext()).load(R.drawable.amalka).into(target)
    
    1. 存储在nodpi,加载为230x541像素位图
    2. 存储在xxhdpi,加载为230x541像素位图

    【讨论】:

      【解决方案2】:

      1.Android会自动缩放图像,以防您为一个屏幕密度提供图像而另一个屏幕没有这样的图像。例如如果你只在 drawable-xxxhdpi 文件夹中添加图片,Android 会为 xxhdpi、xhdpi 屏幕密度等生成图片。

      2.您可以将您的图像保存在一个文件夹中drawable-xxxhdpi,并让Android进行缩小,如果您不喜欢结果,您可以自己创建不同密度的图像。

      name    dencity   scale  
      mdpi    160dpi    x1  
      hdpi    240dpi    x1.5  
      xhdpi   320dpi    x2  
      xxhdpi  480dpi    x3  
      xxxhdpi 640dpi    x4  
      

      3.您可以根据 ImageView 的大小和 dpi 比例定义图像的尺寸。例如,如果您的 ImageView 的宽度为 80dp,高度为 40dp,那么 drawable-mdpi 文件夹的图像大小应为 80x40px,因为 mdpi 是基线密度,对于 drawable-hdpi,那么您需要有图像 120x60px(比例为 1.5)等。对于 @ 987654325@您的图像将是 320x160 像素。

      如果您希望您的图像适合所有设备上的所有屏幕,您可以使用参数android:scaleType="centerCrop",它将使图像占据所有空间,但根据屏幕宽高比可以隐藏一小部分图像。您还可以尝试根据可用屏幕区域的最短尺寸指定图像资源,例如drawable-sw720dp。阅读更多关于此here 的信息。

      【讨论】:

      • 感谢您的回答。 Android真的总是缩放图片吗?我认为毕加索可以使用 BitmapFactory.Options.inScaled 来避免它。我希望它能选择最佳匹配资源。我将创建多个不同的变体来检查它。
      • 如果您不希望您的图像被缩放,您可以将它放在文件夹drawable-nodpi 中。但请确保您在其他可绘制文件夹中没有此类图像,因为如果您这样做,则图像将从其他资源中获取。
      猜你喜欢
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 2012-03-16
      • 1970-01-01
      相关资源
      最近更新 更多