android webview 缩放为什么缩放比例opts.inSampleSize为1,2,3时候图片大小没改变

Android 屏幕分辩率相关问题 - andyhuabing的专栏
- 博客频道 - CSDN.NET
4649人阅读
Android 可设置为随着窗口大小调整缩放比例及设定fixed的窗口大小。对于surface的控制在SurfaceHolder类中进行
而Android 屏幕分辩率中已经有一个类DisplayMetics提供Andorid.util 包下的DisplayMetrics 类提供了一种关于显示的通用信息,如显示大小,分辨率和字体。
为了获取DisplayMetrics 成员,首先初始化一个对象如下:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
String str = metrics.toString();
String str = &屏幕分辨率为:& + metrics.widthPixels
&& & & & & & & &+& * &+metrics.heightP
&& & & &textview.setText(str); //显示
在CTS中有如下一段代码可以体现出不同的单位显示情况:
public void testAccessTextSize() {
DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
mTextView = new TextView(mActivity);
mTextView.PLEX_UNIT_PX, 20f);
assertEquals(TypedValue.PLEX_UNIT_PX, 20f, metrics),
mTextView.getTextSize(), 0.01f);
mTextView.PLEX_UNIT_DIP, 20f);
assertEquals(TypedValue.PLEX_UNIT_DIP, 20f, metrics),
mTextView.getTextSize(), 0.01f);
mTextView.PLEX_UNIT_SP, 20f);
assertEquals(TypedValue.PLEX_UNIT_SP, 20f, metrics),
mTextView.getTextSize(), 0.01f);
// setTextSize by default unit &sp&
mTextView.setTextSize(20f);
assertEquals(TypedValue.PLEX_UNIT_SP, 20f, metrics),
mTextView.getTextSize(), 0.01f);
mTextView.setTextSize(200f);
assertEquals(TypedValue.PLEX_UNIT_SP, 200f, metrics),
mTextView.getTextSize(), 0.01f);
这里面有几个单位dip, dp, px, sp概念必须了解一下先:
dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,
&& & & &这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。&
px: pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。&
pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用;&
sp: scaled pixels(放大像素). 主要用于字体显示best for textsize,根据 google 的建议,
TextView 的字号最好使用 sp 做单位
程序员通常以像素为单位设计计算机用户界面,但是如果显示分辩率发生变更(更高时),
则以前做的应用界面会相应缩小,所以有必要使用与分辨率无关的度量单位解决此问题。
Android支持下列所有单位:
px(像素):屏幕上的点。&
in(英寸):长度单位。&
mm(毫米):长度单位。&
pt(磅):1/72英寸。&
dp(与密度无关的像素):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。
dip:与dp相同,多用于android/ophone示例中。
dp也就是dip。这个和sp基本类似。如果设置表示长度、高度等属性时可以使用dp或sp。但如果
设置字体,需要使用sp。dp是与密度无关,sp除了与密度无关外,还与scale无关。
所以为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为
文字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图
附带两个问题的解决:
解码图片显示时,设定的density会影响到显示效果
在DisplayMetrics.java中定义的默认值:
* Standard quantized DPI for low-density screens.
public static final int DENSITY_LOW = 120;
* Standard quantized DPI for medium-density screens.
public static final int DENSITY_MEDIUM = 160;
* Standard quantized DPI for high-density screens.
public static final int DENSITY_HIGH = 240;
* Standard quantized DPI for extra-high-density screens.
public static final int DENSITY_XHIGH = 320;
* The reference density used throughout the system.
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;&& &
&1、如果图片解码像素高但显示效果不怎么样时,请修改下DENSITY_DEFAULT看个效果
&& public static final int DENSITY_DEFAULT = DENSITY_XHIGH;
&& 显示例子:&&&Options opts = new Options();
opts.inScaled =
opts.inSampleSize = 1;
opts.inScreenDensity = DisplayMetrics.DENSITY_HIGH;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
mBitmapbg = BitmapFactory.decodeResource(this.getResources(), R.drawable.bj, opts);
BitmapDrawable bd = new BitmapDrawable(mBitmapbg);&& &
&& &2、如果图片在不同的显示频率下被放大了,那么有可能与webview相关,这也是density影响的
* Enum for specifying the WebView's desired density.
* FAR makes 100% looking like in 240dpi
* MEDIUM makes 100% looking like in 160dpi
* CLOSE makes 100% looking like in 120dpi
public enum ZoomDensity {
MEDIUM(100),
CLOSE(75);
ZoomDensity(int size) {
那么是否可能根据屏幕的分辩率进行动态设定呢?
int dDensity = getResources().getDisplayMetrics().densityD
WebSettings.ZoomDensity zDensity = WebSettings.ZoomDensity.MEDIUM ;
switch(dDensity) {
case DisplayMetrics.DENSITY_LOW :
zDensity = WebSettings.ZoomDensity.CLOSE;
case DisplayMetrics.DENSITY_MEDIUM:
zDensity = WebSettings.ZoomDensity.MEDIUM;
case DisplayMetrics.DENSITY_HIGH:
zDensity = WebSettings.ZoomDensity.FAR;
webSettings.setDefaultZoom(zDensity);
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:599318次
积分:8879
积分:8879
排名:第791名
原创:151篇
转载:45篇
评论:280条
文章:37篇
阅读:138915
(1)(2)(1)(2)(2)(1)(2)(1)(1)(1)(5)(1)(3)(6)(3)(4)(4)(3)(1)(8)(1)(3)(11)(12)(16)(7)(16)(13)(9)(22)(24)(1)(10)android客户端加载网络大图片如何避免内存溢出 - 劲奇 - 推酷
android客户端加载网络大图片如何避免内存溢出 - 劲奇
在Android开发中加载sdcard上的大图片到内存时容易导致OOM异常,常见的解决办法是
基于BitmapFactory.Options类提供的方法定义指定的解码方式,
设置inJustDecodeBounds属性为true,避免分配内存,返回一个null的Bitmap对象(包含outWidth,outHeightandoutMimeType),然后读取图片的尺寸和类型。再根据屏幕的高和宽对图片进行缩放,最后将缩放的图片加载到内存,主要代码如下:
Options opts = new Options();
opts.inJustDecodeBounds = true; //设置为true, 加载器不会返回图片, 而是设置Options对象中以out开头的字段.即仅仅解码边缘区域
BitmapFactory.decodeFile(filePath, opts);
// 得到图片的宽和高
int imageWidth = opts.outW
int imageHeight = opts.outH
// 获取屏幕的宽和高
Display display = this.getWindowManager().getDefaultDisplay(); // 获取默认窗体显示的对象
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
// 计算缩放比例
int widthScale = imageWidth / screenW
int heightScale = imageHeight / screenH
int scale = widthScale & heightScale ? widthScale:heightS20
// 指定加载可以加载出图片.
opts.inJustDecodeBounds = false;
// 使用计算出来的比例进行缩放
opts.inSampleSize =
Bitmap bm = BitmapFactory.decodeFile(path, opts);
这段代码主要是针对用户存储在sdcard上的大图片,如果现在要从网络上获取一张大图片并在Android机上显示出来,应该如何避免OOM异常呢?
首先加载网络大图片如果是通过BitmapFactory.decodeStream(inputStream)方法的话会出现内存溢出,所以我们同样可以考虑使用Options 类对图片进行缩放处理,然后用BitmapFactory.decodeStream(is, outPadding, opts)方法加载网络图片流对象,但是options的缩放比例该如何确定,如果直接写options.inSampleSize =&固定值;会存在两个问题:一是如果固定值太小任然有内存溢出的可能,二是如果固定值太大会导致加载出来的图片模糊不清,所以现在同样考虑根据图片的高和宽与屏幕的高和宽进行缩放?但是图片都还没加载出来怎样得到图片高和宽呢?你可能会想到通过把options
.inJustDecodeBounds 设置为 然后调用BitmapFactory.decodeStream(is, outPadding, options),再通过options
.outW和options.outH得到图片的高和宽,想法很好,但是当你计算出缩放比再通过options.inJustDecodeBounds =options.inSampleSize =Bitmap bm = BitmapFactory.decodeStream(is, outPadding, options)方法获取缩放后的图片时,你会看到手机界面上啥到没有,再看日志发现输出一行SkImageDecoder::Factory returned null信息,返回的竟然是空对象,郁闷吧,这是为什么呢?原来你在代码中两次使用了BitmapFactory.decodeStream(is, outPadding, options)方法,进一步说是因为你两次使用了同一个InputStream流对象,在第二次使用时流的起始位置已经移动到末尾了,所以返回的是空,那该怎么办呢?我目前使用的方法是分别打开两个流对象,一个用于设置options的缩放比例,一个用于BitmapFactory.decodeStream(is, outPadding, options)方法调用,经过测试我发现如果先设置options后再传递给BitmapFactory.decodeStream时会非常卡,图片老半天加载不出来,所以我换了一种方式:先通过HttpClient得到图片的流对象,获取它的宽高并根据屏幕的宽高计算出缩放比例;然后再通过HttpClient得到图片的流对象,根据计算出的缩放比例进行缩放,主要代码如下:
* 计算图片的缩放比例
public int getScare() {
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(imageUrl);
HttpResponse response = client.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
if (200 == code) {
InputStream is = response.getEntity().getContent();
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, opts);
int imageWidth = opts.outW
int imageHeight = opts.outH
Display display = ImageActivity.this.getWindowManager()
.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
int widthscale = imageWidth / screenW
int heightscale = imageHeight / screenH
int scale = widthscale & heightscale ? widthscale :
} catch (Exception e) {
e.printStackTrace();
return 1;//网络连接失败时默认返回1
* 获取网络图片
protected void getNetImage() {
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(imageUrl);
HttpResponse response = client.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
if (200 == code) {
InputStream is = response.getEntity().getContent();
Options opts = new Options();
//根据计算出的比例进行缩放
int scale = getScare();
opts.inSampleSize =
Bitmap bm = BitmapFactory.decodeStream(is, null, opts);
//将bm发生给主线程用于显示图片,更新UI
Message msg = Message.obtain();
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
//显示图片
Handler handler = new Handler() {
public void handleMessage(Message msg) {
Bitmap bm = (Bitmap) msg.
iv.setImageBitmap(bm);
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见

我要回帖

更多关于 android图片手势缩放 的文章

 

随机推荐