专栏首页陶士涵的菜地[android] 加载大图片到内存

[android] 加载大图片到内存

默认情况下,android程序分配的堆内存大小是16,虚拟机上面的VM Heep就是设置它的

一个图片所占的内存,比如1920*2560像素的图片需要,1920*2560*3至少这些的内存byte

找到ImageView控件对象

调用BitmapFactory对象的decodeFile(pathName)方法,来获取一个位图对象,参数:pathName是String类型的图片路径

把图片导入到手机的sdcard目录下面

调用ImageView对象的setImageBitmap(bitemap)方法,参数:Bitemap对象

此时会报内存溢出的错误

我们需要对图片进行缩放

手机的分辨率比如:320*480 图片的分辨率比如:2000*4000

分别计算比例,2000/320 4000/480,按照大的那个比例进行缩放

调用重载方法BitmapFactory对象的decodeFile(pathName,opts),参数:路径,Options对象

获取BitmapFactory.Option对象,通过new Options()方法

设置Options对象的属性inJustDecodeBounds为ture,仅解析头部信息数据

获取Options对象的outHeight属性,值为图片的高度

获取Options对象的outWidth属性,值为图片的宽度

获取WindowManager对象,通过getSystemSerivce()方法,参数:WINDOW_SERVICE

调用WindowManager对象的getDefaultDisplay().getHeight()或getWidth()方法,获取宽高

计算宽和高的缩放比例

判断,当比例大于1的时候,找出宽高里面的大的值作为图片缩放比例

计算完比例之后

设置Options对象的属性inJustDecodeBounds为false,真解析图片

设置Options对象的采样率属性inSampleSize为上面计算的大的比例

调用重载方法BitmapFactory对象的decodeFile(pathName,opts),获取到Bitmap对象

调用ImageView对象的setImageBitmap(bitemap)方法,参数:Bitemap对象

exif是图片文件的头信息

获取ExifInterface对象,通过new出来

调用ExifInterface对象的getAttribute()方法,获取图片的信息,参数:tag

ExifInterface.TAG_DATETIME 拍摄时间

ExifInterface.TAG_MODEL 拍摄相机

代码:

package com.tsh.loadbigimg;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private ImageView iv_img;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv_img=(ImageView) findViewById(R.id.iv_img);
        
    }
    //加载大图片
    public void load(View v){
        Options opts=new Options();
        opts.inJustDecodeBounds=true;
        BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
        //图片的宽高
        int imgWidth=opts.outWidth;
        int imgHeight=opts.outHeight;
        
        //屏幕的宽高
        WindowManager wm=(WindowManager) getSystemService(WINDOW_SERVICE);
        int windowHeight=wm.getDefaultDisplay().getWidth();
        int windowWidth=wm.getDefaultDisplay().getWidth();
        
        int scaleX=imgWidth/windowWidth;
        int scaleY=imgHeight/windowHeight;
        System.out.println("x比例:"+scaleX);
        System.out.println("y比例:"+scaleY);
        //计算缩放比例
        int scale=1;
        if(scaleX>scaleY&&scaleY>1){
            scale=scaleX;
        }
        if(scaleY>scaleX&&scaleX>1){
            scale=scaleY;
        }
        System.out.println("比例:"+scale);
        opts.inJustDecodeBounds=false;
        opts.inSampleSize=scale;
        Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
        iv_img.setImageBitmap(bitmap);
        
    }
    //读取信息
    public void read(View v){
        try {
            ExifInterface exif=new ExifInterface("/sdcard/a.jpg");
            String date=exif.getAttribute(ExifInterface.TAG_DATETIME);
            String model=exif.getAttribute(ExifInterface.TAG_MODEL);
            System.out.println("相机:"+model+";时间:"+date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [android] 在不同的activity之间传递数据

    添加<TextView/>控件,设置控件内容水平居中,android:gravity=”center_horizontal”

    陶士涵
  • [android] 采用服务录制电话&服务的生命周期

    调用MediaRecorder对象的setAudioSource()方法,设置音频源,

    陶士涵
  • [android] listview入门

    Listview组件非常重要,4分之一的时间都是在搞这个,还是通过上一节的数据库,写个for循环,插入50条数据。

    陶士涵
  • springMvc4+hibernate4的一个奇葩的网上众说纷纭的错误

    springMvc4+hibernate4项目运行报错如下: org.hibernate.HibernateException: Could not obtai...

    小柒2012
  • DDD是如何解决复杂业务扩展问题?

    业务初期,功能比较简单,CRUD基本可以满足。但随着系统的不断演化,业务系统越来越复杂,各模块间有着千丝万缕的关系,如何提升其扩展性,避免牵一发而动全身,是我们...

    用户7676729
  • 使用FlashWavRecorder实现浏览器录制wav音频和上传音频文件,兼容IE8以上浏览器

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    eguid
  • 到底该用img还是background-image?

    在前端页面的实现过程中,我们经常会遇到这个情况:有一个盒子,盒子里面需要放一张图片。这个时候,我们既可以通过添加image标签来实现,也可以通过设置背景图的形式...

    木子墨
  • DeepMind发布Acme,高效分布式强化学习算法框架轻松编写RL智能体

    DeepMind 本周发布了一个强化学习优化框架 Acme,可以让AI驱动的智能体在不同的执行规模上运行,从而简化强化学习算法的开发过程。

    新智元
  • 5分钟面试指南(第二篇 python8荣八耻)

    本部分我们会为大家提供一些python初级工程师在面试过程中遇到的常见的面试题目,期望达到的效果:

    还是牛6504957
  • 介绍-The Boost C++ Libraries

    Boost C ++库是基于C ++标准的现代库的集合。源代码是根据Boost软件许可发布的,该许可允许任何人免费使用,修改和分发这些库。这些库是独立于平台的,...

    ccf19881030

扫码关注云+社区

领取腾讯云代金券