Android中的多媒体显示之图片缩放
一:图片OOM异常:
代码示例:
public class MainActivity extends Activity {
private ImageView iv_imageView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_imageView = (ImageView) findViewById(R.id.Iv_imageView);
}
public void load(View view){
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg");
iv_imageView.setImageBitmap(bitmap);
}
}
出现问题:
解析问题:
一:图片明明就:1.37MB(1,444,582字节),为什么vm为16MB还会报错-->OOM?
1.图片要想被加载到内存中显示,在内在中是以数组的方式保存的,用数组表示图片中的每一个像素,
2.这个图片虽然只有1.37MB,但其分辨率为:2592*1944=5038848,即在内存中要表示这么多个点!
3.每个点都是有颜色的,RGB,所以每表示一个颜色,至少需要3个Byte来表示!
4.图片支持都有透明度的,图片的每个点都有一个参数&(0-255),1个字节,所以要表示一个点,需要四个Byte!
5.5038848*4=20155392Byte ---> 20155392/1024=19683KB ---> 19638/1024=19.2216796875MB,即要将那个1.37MB的图片表示在计算机内存中,需要19.2216796875MB的内存,大于VM Heap:16MB,故OOM!
6.所以图片要显示在手机内存中要进行相应的处理,不能直接显示原图!一般所建的模拟器屏幕也就320*480,即只能表示这么多的像素。所以原图的每个点不能完全显示在手机的屏幕上!所以将图片依据手机屏幕做相应的缩放
二:对图片进行缩放的算法:
1.获取手机屏幕的分辨率:宽,高:320*480
2.获取图片的宽高信息:2592*1944
3.计算图片的缩放比例:
水平方向:2592/320=8.1
竖直方向:1944/480=4.05
4.确定显示的缩放比例:取大的一方(否则显示不全!)9.1
5.缩放完毕后,加载显示图片
详细代码:
public class MainActivity extends Activity { private ImageView iv_imageView;
private int windowWidth;
private int windowHeight;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_imageView = (ImageView) findViewById(R.id.Iv_imageView); //1.获取手机屏幕的分辨率 宽高
Display display = getWindowManager().getDefaultDisplay();
windowWidth = display.getWidth();
windowHeight = display.getHeight();
System.out.println("屏幕的宽度:" + windowHeight);
System.out.println("屏幕的高度:" + windowHeight);
}
public void load(View view){
// Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg");
// iv_imageView.setImageBitmap(bitmap);
Options opts = new Options();
//2.0设置解析器不去真正的解析这个位图,而是解析这个图片的out输出信息(宽度,高度),不会为图片的每个点申请内在空间
opts.inJustDecodeBounds = true;
//2.得到图片的宽高信息
BitmapFactory.decodeFile("/sdcard/1.jpg",opts);
int picHeight = opts.outHeight;
int picWidth = opts.outWidth;
System.out.println("图片的宽度:" + picWidth);
System.out.println("图片的高度:" + picHeight); //3.得到缩放比例
int scaleX = picWidth/windowWidth;
int scaleY = picHeight/windowHeight;
System.out.println("水平缩放比例:" + scaleX);
System.out.println("竖直缩放比例:" + scaleY); //3.2. 确定缩放比例:
int scale = 1;
if(scaleX > scaleY && scaleY>1){
scale = scaleX;
}
if(scaleY > scaleX && scaleX>1){
scale = scaleY;
} System.out.println("最终确定的缩放比例:" + scale); //4.真正的解析这个图片
opts.inJustDecodeBounds = false;
opts.inSampleSize = scale; Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/1.jpg",opts);
iv_imageView.setImageBitmap(bitmap);
}
}
运行时log:
09-29 16:05:37.715: I/System.out(23786): 屏幕的宽度:480
09-29 16:05:37.715: I/System.out(23786): 屏幕的高度:480
09-29 16:07:12.085: I/System.out(23786): 图片的宽度:2592
09-29 16:07:12.085: I/System.out(23786): 图片的高度:1944
09-29 16:07:12.105: I/System.out(23786): 水平缩放比例:8
09-29 16:07:12.115: I/System.out(23786): 竖直缩放比例:4
09-29 16:07:12.115: I/System.out(23786): 最终确定的缩放比例:8
此时图片能正确显示:
09-29 16:17:26.475: I/System.out(23786): 屏幕的宽度:320
09-29 16:17:26.475: I/System.out(23786): 屏幕的高度:320
09-29 16:17:33.336: I/System.out(23786): 图片的宽度:1280
09-29 16:17:33.336: I/System.out(23786): 图片的高度:1024
09-29 16:17:33.345: I/System.out(23786): 水平缩放比例:2
09-29 16:17:33.345: I/System.out(23786): 竖直缩放比例:3
09-29 16:17:33.345: I/System.out(23786): 最终确定的缩放比例:3
Android中的多媒体显示之图片缩放的更多相关文章
- Android中同一个ImageView中根据状态显示不同图片
一般: if(条件1) { image.setBackground(R.id.xxx1); } else if (条件2) { image.setBackground(R.id.xxx2); } 实际 ...
- Android中高效的显示图片之一 ——加载大图
在网上看了不少文章,发现还是官方文档介绍最详细,把重要的东西简单摘要出来.详细可看官方文档地址 ( http://www.bangchui.org/read.php?tid=9 ) . 在应用中显示图 ...
- Android中高效的显示图片之三——缓存图片
加载一张图片到UI相对比较简单,如果一次要加载一组图片,就会变得麻烦很多.像ListView,GridView,ViewPager等控件,需要显示的图片和将要显示的图片数量可能会很大. 为了减少内存使 ...
- android多点触控自由对图片缩放
在系统的相册中,观看相片就可以用多个手指进行缩放. 要实现这个功能,只需要这几步: 1.新建项目,在项目中新建一个ZoomImage.java public class ZoomImageView e ...
- [置顶] Android中使用Movie显示gif动态图
转载请注明: http://blog.csdn.net/u012975705/article/details/48717391 在看这篇博文之前对attr自定义属性还是不是很熟的童鞋可以先看看:An ...
- 【有人@我】Android中高亮变色显示文本中的关键字
应该是好久没有写有关技术类的文章了,前天还有人在群里问我,说群主很长时间没有分享干货了,今天分享一篇Android中TextView在大段的文字内容中如何让关键字高亮变色的文章 ,希望对大家有所帮助, ...
- android中Canvas使用drawBitmap绘制图片
1.主要的绘制图片方法 //Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置 drawBitmap(Bitmap bitmap, float left, float ...
- Android中高亮变色显示文本中的关键字
应该是好久没有写有关技术类的文章了,前天还有人在群里问我,说群主很长时间没有分享干货了,今天分享一篇Android中TextView在大段的文字内容中如何让关键字高亮变色的文章 ,希望对大家有所帮助, ...
- Android中高效的显示图片之二——在非UI线程中处理图片
在“加载大图”文章中提到的BitmapFactory.decode*方法,如果源数据是在磁盘.网络或其它任何不是在内存中的位置,那么它都不应该在UI线程中执行.因为它的加载时间不可预测且依赖于一系列因 ...
随机推荐
- cursor 与refcursor及sys_refcursor的区别 (转载)
楼主标明是转载的,我只把我转载的地址发上来 http://www.cnblogs.com/honliv/archive/2011/07/21/2112639.html 显式是相对与隐式cursor而言 ...
- 关于模板中的动态取值 ---反射与javascript脚本编译
在项目中经常遇到一个问题,打印word或者打印excel的时候,我们经常使用一对一的赋值或者批量替换的方式来对模板进行修改. 但是现在遇到两种场景: 1.取值是通过自定以方法进行取值的. 如:一个销售 ...
- 重新开始学习javase_集合_List
一,List之ArrayList(转:http://blog.csdn.net/zheng0518/article/details/42198205) 1. ArrayList概述: ArrayLis ...
- Hibernate 一对多双向关联Demo
以Classes[班级]和Student[学生]为例的Demo //Classes.java public class Classes implements Serializable { privat ...
- c#中使用ABCpdf处理PDF
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- 10分钟 教你学会Linux/Unix下的vi文本编辑器
10分钟 教你学会Linux/Unix下的vi文本编辑器 vi编辑器是Unix/Linux系统管理员必须学会使用的编辑器.看了不少关于vi的资料,终于得到这个总结.不敢独享,和你们共享. 首先,记住v ...
- IOC-控制反转(Inversion of Control),也成依赖倒置(Dependency Inversion Principle)
基本简介 IoC 亦称为 “依赖倒置原理”("Dependency Inversion Principle").差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,这可 ...
- python模块中的特殊变量
37.模块的特殊变量: 显示模块中的变量 import s1 print(vars(s1)) 1.__doc__:打印注释信息. #!/usr/bin/env python # _ ...
- Python学习笔记:02数据类型
Python 数据类型 python中标准的数据类型有 基础类型 整型(长整型) 浮点型 复数型 布尔型 序列类型 字符串 列表 元组 字典 整型 整型和长整型并不严格区分,整型int的表达范围和计算 ...
- 用java模拟银行柜台排队
4年前在办理银行业务的时候,看到每个办理柜台窗口前都有很多人排队. 同时在那个时间段,我正好重温了数据结构这本书.好像里面有提到银行. 所以当时就用java写了一段小程序来模拟窗口排队的情况. 有兴趣 ...