Android图片资源的缩放问题

1.  图片缩放后对齐的问题

在Android的开发中,如何使用图片对很多开发人员是一个很头痛的事。最常见的问题是在一台手机上调试好的UI,在不同dpi的手机上会变形。

Android提供了适配不同dpi的方案,每种dpi都有对应的资源目录。但是我们在开发程序时,对图片资源却不能这样处理,因为图片资源太大,如果我们每种类型的dpi都使用一套图片,应用的尺寸就会急剧膨胀,这可不是我们想看到的结果。

如果只有一套图片,但是有drawable,drawable-mdpi,drawable-hdpi等好几个目录,到底放在哪个目录下才能保证在每种dpi的设备上都显示正确了?这个问题无法给出一个简单的答案,只能是根据具体情况分析。

首先,我们要理解图片放在这些目录下会有什么样的后果:

q drawable目录:这个是所谓的“缺省”目录。如果把图片放在这里,从最终效果上讲,和放在drawable-mdpi目录下是一样的。

q drawable-nodpi目录:放在这个目录下的图片被装载进内存后,不会被缩放,所谓不缩放的意思是一张72x72像素的图片,在内存中的大小仍然是72x72像素。但是在不同的设备上这张图片看起来大小会不一样。

q drawable-mdpi,drawable-xdpi,dreawable-xhdpi:如果将图片放在这些和dpi相关的目录下,当程序运行在相同dpi的设备上时,不会被缩放;当运行在dpi不相同的设备上时,会根据dpi之间的换算关系进行缩放。

对于放在drawable-nodpi下的图片比较简单,不用太多解释。但是对于放在其他目录下的图片,Android对图片缩放的目的是什么呢?其实目的和在layout文件中使用dp做为数量单位一样,是为了让一张图片在不同dpi的设备上看起来大小一样。例如,一张放在drawable-mdpi目录下,大小为72x72像素的图片,如果运行在mdpi的设备上,大小还是72x72像素,但是运行在drawable-hdpi的设备上时,尺寸就会被放大为108x108像素。

如果不考虑图片缩放的效果,通过缩放能够让应用适应不同的屏幕,不是很好吗?为什么开发人员还会觉得头痛呢?这是因为在开发中,很多UI效果是通过拼图的方式实现的,如果两张图片缩放后无法对齐,哪怕只有一个像素,也会让效果失色。要解决这个问题,先让我们看看Android是如何进行缩放的。

Android上最常见的四种dpi是ldpi(120dpi),mdpi(160dpi),hdpi(240dpi)和xhdpi(320dpi)。这四种dpi的比值是120:160:240:320,化简后就是3:4:6:8。放在mdpi目录下的文件,在不同dpi的设备上缩放后的大小就是n*3/4,n*4/4,n*6/4和n*8/4(n为图片大小),如果希望放在mdpi下的图片缩放的效果最好,图片的尺寸必须是4的倍数,否则算法在处理图片的过程中,会不按比例的加入或删除几行(或几列)的像素,这样两张图片中的线条在缩放后就可能会相互错开几个像素。同理,放在ldpi下的图片,大小最好是3的倍数;放在hdpi下的图片,大小最好是6的倍数;放在xhdpi下的图片,大小最好是8的倍数。当然我们并不是要求每一张图都要符合这个规律,但是对于哪些需要精确对齐的图片,这样做还是有必要的。所以一套图片放在哪个目录下不是关键,关键是要确定图片的大小。

注意,这里谈论的图片缩放问题是指在图片装载进内存时就会进行的缩放。除此以外,很多widget在使用图片时还会再次缩放。当然Android也提供了方法禁止widget缩放。例如最常用的ImageView类可以通过设置scaleType属性为“center”来禁止缩放,或者把ImageView的宽度和高度设为“wrap_content”。但是要明白的是,这里设置了让ImageView不去缩放图片,图片装载时还是会被系统缩放的,很多开发人员在这里迷惑了,以为设置了Widget禁止缩放后,显示效果会和原图一样,折腾很长时间也不知道问题出在哪。

如果正在使用的widget也会去缩放图片,同样也要注意缩放的大小问题,原则也是要让每种图片按相同整数倍进行缩放。还要注意的是,在很多情况下,我们在布局上会让UI的宽度撑满整个屏幕。但是很多相同dpi,差不多大小的设备,它们的屏幕分辨率也可能有细微差别,这样如果根据屏幕宽度来缩放,可能有的设备看上去很完美,有的设备却还是对不齐。这种情况下,如果希望达到最佳效果,只能是根据dpi还有屏幕的宽度来动态的计算出一个最佳的宽度了,既要尽可能的占满屏幕,又要让缩放符合比例。但是这样就太麻烦了,而且也未必在所有的情况下都能有这么一个完美值。最好的办法还是在明白问题所在后,从UI设计上就要避免这种问题的出现。所以类似的问题没有一劳永逸的解决方案,需要我们根据实际情况来调整。

2.  NinePatch图片的缩放

NinePatch
图片是Android中定义的一种特殊的图片格式,它通过在普通图片的边缘做标记的方式把一张图片分成9个部分。如下所示:

对NinePatch图缩放时,图片中1,3,7,9四个角保持不变。2号和8号区域水平缩放,4号和6号区域垂直缩放,5号区域则全缩放。

但是对NinePath图片最大的误解就是NinePatch的四个角是绝对不缩放的。除非图片是放在目录drawable-nodpi下,或者是运行在相同dpi的设备上,NinePath图片装载进内存时一样会先根据dpi的比值进行缩放。所谓四个角不缩放,是指装载进内存后,再调用缩放函数进行缩放时,四个角的尺寸不会再变化了。所以我们在制作圆角的NinePathc图时要注意,指定的四个角的大小也要符合前面讲的规律,根据所放目录的dpi来决定四个角的像素大小。

3.  为图片指定Density

Android装载图片时会根据当前设备的dpi进行缩放。我们也能在Bitmap类里或BitmapDrawable类里调用setDensity()和setTargetDesnsity()来改变一张图片的缩放比例。

publicfinal class Bitmap implements Parcelable {

public void setDensity(intdensity);

......

}

publicclass BitmapDrawable extends Drawable {

public void setTargetDensity(intdensity);

......

}

当调用这两个方法后,图片将不按照缺省的density来缩放,而是根据我们指定的density。

时间: 2024-10-11 04:04:23

Android图片资源的缩放问题的相关文章

使用Android的硬件缩放技术优化执行效率

Unity3D研究院之使用Android的硬件缩放技术优化执行效率 http://www.xuanyusong.com/archives/3205 Android中GLSurfaceView在横竖屏切换时重新创建表面缓冲导致的问题 http://blog.k-res.net/archives/1702.html https://stackoverflow.com/questions/7185644/android-opengl-crazy-aspect-ratio-after-sleep

android关于图片缩放

网上有许多关于图片缩放的demo,本人都感觉不怎么好用,最近在github看到了 一个简单的支持多指缩放图片的Android View类 gesture-imageview (地址:https://github.com/jasonpolites/gesture-imageview),感觉还挺好用的,现在写个demo方便以后用于调用 第一步:添加库,推荐直接下载zip,导入工程后,直接将main里的com.polites.android包直接复制到自己的工程中,方便自己以后修改 第二步:由于我只需

Android图片旋转,缩放,位移,倾斜,对称完整示例(二)——Bitmap.createBitmap()和Matrix

MainActivity如下: package cc.c; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.widget.ImageView; /** * Demo描述: * 利用B

Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix

MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.app.Activity; import android.graphics.Matrix; /** * Demo描述:

Android拖动和缩放图片

Android拖动和缩放图片 2014年5月9日 我们在使用应用其中常常须要浏览图片.比方在微信其中.点击图片之后能够对图片进行缩放. 本博客介绍怎样对图片进行拖拽和缩放.这首先要了解Android中的触摸机制了,在屏幕中有手指按下.手指抬起.手指移动还有多个手指触摸的动作. 我们要实现对图片的拖拽和缩放就是要基于这些动作来进行逻辑处理. 图片的拖拽主要是计算手指開始的位置与当前手指的位置关系,来进行平移的,详细能够看代码. 图片的缩放就涉及到计算两点之间的距离来得到缩放比,调用矩阵方法来达到缩

Android图片资源处理

Android用到的图片资源一般指三种:png/jpg等位图文体,.9文件,selector xml文件,在之前的开发中,都放在drawable目录下,但使用最新的Android Studio时,我们会发现所有的登录icon被默认放在了mipmap目录下,并且在不同子目录下放着不同尺寸的图片.是不是在新版本中,所有的位图资源都移到mipmap目录下了呢,我们去官方开发指南中可以看到,drawable和mipmap目录使用解释如下: 也就是说,除了登录使用的icons放在mipmap目录下,其他i

android的ScaleGestureDetector缩放类详解

文章由多出组合,它们来自: http://elvajxw.iteye.com/blog/1308452 http://www.cnblogs.com/lknlfy/archive/2012/03/11/2390274.html 类概述       根据接收的 MotionEvent,  侦测由多个触点(多点触控)引发的变形手势.callback 方法ScaleGestureDetector.OnScaleGestureListener  会在特定手势事件发生时通知用户. 该类仅能和Touch事件

Android图片旋转,缩放,位移,倾斜,对称完整演示样例(一)——imageView.setImageMatrix(matrix)和Matrix

MainActivity例如以下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.app.Activity; import android.graphics.Matrix; /** * Demo描

Android图片的缩放效果

一.概述 Android 图片要实现:手势滑动,双击变大,多点触控的效果. 其实是有一定难度的,我们需要用Matrix ,GestureDetector 等等需要完成一个复杂的逻辑才能实现,然而今天我要说的并不是这种方法,而是一个第三方库Photoview,它使得完成图片缩放工作只需要3-5行代码就搞定了. 是不是很爽... 二.使用方法 github:https://github.com/chrisbanes/PhotoView 如果用AS需在引入如下库文件(目前是最新的): dependen