欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 实现加载大图片的方法

程序员文章站 2023-03-28 11:17:47
项目简介: 该项目为加载大图片 详细介绍: 对于超大的图片,如果不缩放的话,容易导致内存溢出。而经过处理后,无论多大的图片,都能够在手机屏幕上加载出来,不会导致内存溢...

项目简介:

该项目为加载大图片

详细介绍:

对于超大的图片,如果不缩放的话,容易导致内存溢出。而经过处理后,无论多大的图片,都能够在手机屏幕上加载出来,不会导致内存溢出。当然,脸黑的除外

该应用涉及到的知识有:

- 1.bitmap的使用

- 2.android手机中加载图片的原理

  有的时候,我们加载一张不足1m的图片,尽管手机的堆内存有16m,仍然会导致内存溢出,why?

  这就更计算机加载图片的原理有关了:

  1).手机会解析图片的所有像素信息,把每个像素信息都存入到内存中

  2).android中保存图片是用argb保存的,a表示阿尔法透明度,所以一个像素点占用了4个字节

例如:一张1080*720像素的24位位图图片,可能实际上经过压缩后大小只有几十k,而在android手机加载这张图片所需要的内存大小为:

1080*720*(3+1)=3110400 byte = 3037 kb = 2.9mb

实际上,图片中还包含一点其他的信息,例如图片保存的格式,使用的相机名称,以及拍摄时间等,所以总体来说要比3110400字节大一旦,大概多上几十个字节

步骤:

1.创建一个android项目,编写布局文件:

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="hhh.exercise.smultimedia_a_image.mainactivity" >

 <edittext
  android:id="@+id/ed"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:gravity="center"
  android:text="a.jpg"
  android:textcolor="#00ff00"
  android:textsize="30sp" />

 <requestfocus />

 <button
  android:onclick="see"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="点击看片"
  android:textcolor="#00ffff"
  android:textsize="30sp" />

 <imageview
  android:id="@+id/iv"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_gravity="center"
  android:src="@drawable/ic_launcher" />
</linearlayout>

界面如下所示:

Android 实现加载大图片的方法

2.在mainactivity中编写代码:

public class mainactivity extends activity {
 private edittext ed;
 private imageview iv;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  ed = (edittext) findviewbyid(r.id.ed);
  iv = (imageview) findviewbyid(r.id.iv);
 }
 public void see(view view) {
  // 确定要加载的图片(这里为了调试方面,把所有的图片都放在sd卡中,然后在界面上输入图片的名字,根据给名字拼接字符串)
  string filename = ed.gettext().tostring();
  string path = environment.getexternalstoragedirectory().getpath()+ "/" + filename;

  // 该类为位图工厂(bitmapfactory)的内部类,用来封装参数对象
  options opts = new options();

  // 不为像素申请内存,只获取图片的宽、高信息
  // injustdecodebound该字段设置为true,那么位图工厂构建bitmap对象时返回的是空值,但是会把图片的一些信息返回在options对象中(如图片的宽、高等)
  opts.injustdecodebounds = true;

  // 第二个参数是解析图片时传入的参数,由于可能传入的参数过多,所以直接把所有参数封装成一个对象
  bitmapfactory.decodefile(path, opts);

  // 获取图片的额宽高
  int imgwidth = opts.outwidth;
  int imgheight = opts.outheight;

  // 获取当前手机屏幕的宽高
  display dp = getwindowmanager().getdefaultdisplay();
  int screenwidth = dp.getwidth();
  int screenheight = dp.getheight();

  // 设置默认缩放比为1
  int scale = 1;

  // 计算图片宽高与屏幕宽高比例,即计算宽缩放比,高缩放比
  int scalewidth = imgwidth / screenwidth;
  int scaleheight = imgheight / screenheight;

  // 选择缩放比例,如果图片比屏幕小,就不进行缩放.如果图片比屏幕大,但是宽高缩放比例不同,选择缩放比大
  if (scalewidth >= scaleheight && scalewidth > 1) {
   scale = scalewidth;
  } else if (scalewidth < scaleheight && scaleheight > 1) {
   scale = scaleheight;
  }
  // 在options的对象中设置缩放比例
  opts.insamplesize = scale;
  // 一定要把injustdecodebound该字段设置为false,实际上默认值是false,
  // 但是在前面的代码中已经改为了true,所以要更改过来。当然,也可以重新new 一个option是对象
  opts.injustdecodebounds = false;
  bitmap bm = bitmapfactory.decodefile(path, opts);
  iv.setimagebitmap(bm);
 }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!