[android] 加载大图片到内存详解手机开发

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

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

 

找到ImageView控件对象

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

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

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

此时会报内存溢出的错误

 

我们需要对图片进行缩放

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

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

 

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

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

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

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

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

 

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

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

 

计算宽和高的缩放比例

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

 

计算完比例之后

设置Options对象的属性inJustDecodeBoundsfalse,真解析图片

设置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(); 
        } 
         
    } 
}

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/5453.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论