加载大图片到内存的合理方法

图形图像处理

先明确几个概念。
1.关于单位:计算机中最小单位是比特bit,即一个0或者一个1,计
算机存储文件是以byte为单位,byte是字节等于8个比特。
1M=1024kb;1kb=1024byte;1byte=8bit;

2.计算机如何表示图形:以像素为单位,组合成一张图片,图像的分辨率就是像素的个数。比如一张图片的分辨率是1028*720,这张图片就由1028*720个像素点组成。组成图片的像素点越多,对图片细节的描绘就越精确,表现出来的就是更加清晰。照相机的像素越高(应该说分辨率越高)拍出的照片越清晰就是这个道理,500万像素就表示拍出的一张照片由500w个像素组成。

3.计算机存储图像:存储每个像素的颜色,假如以32位位图的格式存储,每个像素需要32bit也就是4个byte,计算一下,1028*720*4/1024/1024=2.82M 需要2.82M的空间存储这张图片。不过计算机中有很多的图片压缩方式,比如黑白照片一个bit就可以表示一个像素,相当而言占用空间是非常小的。
android下使用的是RGB表示颜色。RGB:red green blue,#ff ff ff .#FF FF FF表示白色,#000000表示黑色。

4.Android系统在内存中表示一个像素的颜色需要32位,以16进制表示:0x FF FF FF FF ,第一个FF代表透明度,依次为,红色,绿色,蓝色。一个int的值时32位,一个int值可以代表计算机中一个像素的颜色。

5.大部分Android手机系统给每个应用程序分配的内存大小为16M,当应用程序申请的内存超过这个值时,会报OOM(out of memory)内存溢出,应用会崩溃。android加载图片需要的内存跟图片占用空间的大小没有一点关系,而是由图片的分辨率决定,比如分辨率是1028*720,需要申请的内存是1028*720个像素,如果以32位的位图格式加载图片,每个像素需要32bit也就是4个byte,计算一下,1028*720*4/1024/1024=2.82M。需要申请2.82M的内存。即使是一张黑白照片,它的分辨率是1028*720那么所要申请的内存空间也是2.8M。

加载大图片到内存中

手机屏幕都是有既定的分辨率的,一个屏幕最多有多少个像素点是固定的,分辨率很大的图片即使加载进内存中也有可能不能完全显示出来,所以我们在Android中加载大图片时候要先将图片缩放,缩放的原理简单说就是将周围数十个像素点用一个像素点来表示,以人眼的分别能力感觉不出来太明显的变化。根据图片实际大小和手机屏幕分辨率大小的比例进行缩放。代码如下:

public void click(View view){
        //相当消耗内存资源 根据图片的分辨率而定
        // Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg");
        // iv.setImageBitmap(bitmap);

        //1.得到屏幕的宽高信息
        WindowManager wm = getWindowManager();
        int screenWidth = wm.getDefaultDisplay().getWidth();
        int screenHeight = wm.getDefaultDisplay().getHeight();
        System.out.println("屏幕宽高:"+screenWidth+"-"+screenHeight);

        //2.得到图片的宽高。
        BitmapFactory.Options opts = new Options();//解析位图的附加条件
        opts.inJustDecodeBounds = true;//不去解析真实的位图,只是获取这个位图的头文件信息
        Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg", opts);
        int bitmapWidth = opts.outWidth;
        int bitmapHeight = opts.outHeight;
        System.out.println("图片宽高: "+bitmapWidth+"-"+bitmapHeight);

        //3.计算缩放比例
        int dx = bitmapWidth/screenWidth;
        int dy = bitmapHeight/screenHeight;
        int scale = 1;
        if(dx>dy&&dy>1){
            System.out.println("按照水平方法缩放,缩放比例:"+dx);
             scale = dx;
        }

        if(dy>dx&&dx>1){
            System.out.println("按照垂直方法缩放,缩放比例:"+dy);
            scale = dy;
        }
        //4.缩放加载图片到内存。
        opts.inSampleSize = scale;
        opts.inJustDecodeBounds = false;//真正的去解析这个位图。
        bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg", opts);
        iv.setImageBitmap(bitmap);
    }

你可能感兴趣的:(Android优化)