缩放位图以及简单的图形处理

Android程序中需要加载特别大的照片时,(指的是照片的分辨率不得超过手机屏幕大小,)

此时内存吃不消,需要缩放图片,否则可能出现OOM(Out Of Memory)即内存溢出。

如下图:

 

 

  1. 首先解析一下基本的知识:  
  2.   
  3. 位图模式,bitmap颜色位数是1  
  4.   
  5. 灰度模式,bitmap颜色位数是8位,和256色一样  
  6.   
  7.    
  8.   
  9. RGB模式,bitmap颜色位数是24 RGB模式下,一个像素对应的是红、绿、蓝三个字节  
  10.   
  11. CMYK模式,bitmap颜色位数是32  CMYK模式下,一个像素对应的是青、品、黄、黑四个字节  
  12.   
  13. 图像文件的字节数(Byte) = 图像分辨率*颜色深度/8(bit/8)  
  14.   
  15. 例如:一幅640*480图像分辨率、RGB色一般为24位真彩色,图像未经压缩的数据容量为:640X480X24/8921600字节=900KB(1KB=l千字节=1024字节)。  
  16. 注:一个图像文件占的磁盘空间大小还和磁盘的文件格式有关。如:NTFS最小单位为4KB 所以图像文件大小肯定是4KB的倍数。但是有图图片压缩算法的存在,图片文件在保存时,体积要比在内存的大小小得多,如640x480的图片文件大小一般只在200K~300K。这也是为什么,加载几MB的图片文件,会导致JVM内存溢出,导致OutofMemoryException的原因。  
  17.   
  18.    
  19.   
  20. 由上面的公式,我们可以得出,加载的图片所占的内存大小,取决于其分辨率和颜色数。  
  21.   
  22.    
  23.   
  24. 我们再来看看Google官方的介绍:  
  25.   
  26.    
  27.   
  28. 这个已经非常的明白了,我们VM的app进程所获得的内存只有区区的16MB,普普通通的5MP摄像头拍出来的图片,直接加载,将占用接近19MB的内存。可见,不进行压缩,内存将会直接溢出。  

 

 

  

 

来自 <http://blog.csdn.net/life02/article/details/7992727>

 

 

我在程序中通过两种方式来解决问题:

1.采用BitmapFactory.Options 直接缩放:

 

BitmapFactory.Options bmpFactoryOptions = newBitmapFactory.Options();

bmpFactoryOptions.inSampleSize = 8;

Bitmap bmp =BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

imv.setImageBitmap(bmp);

 

 

2.

根据当前屏幕分辨率的大小,加载图片

 

Display currentDisplay =getWindowManager().getDefaultDisplay();

int dw = currentDisplay.getWidth();

int dh = currentDisplay.getHeight();

BitmapFactory.OptionsbmpFactoryOptions = new BitmapFactory.Options();//解析位图的附加条件

bmpFactoryOptions.inJustDecodeBounds= true; //允许调用者查询位图信息,并且不需要加载到内存中,不去解析真实的位图,只是获取这个位图的头文件信息

Bitmap bmp =BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

int bitmapWidth = bmpFactoryOptions.outHeight;

int bitmapHeight = bmpFactoryOptions.outWidth;

int dx=bitmapWidth/dw;

Int dy=bitmapHeight/dh;

Int scale=1;

if(dx>dy&&dy>1){

scale=dx;//按水平方向缩放图片。

}

if(dy>dx&&dx>1){

scale=dy;

}

bmpFactoryOptions.inSampleSize=scale;

bmpFactoryOptions.inJustDecodeBounds= false;//真正的去解析这个位图;

bmp = BitmapFactory.decodeFile(imageFilePath,bmpFactoryOptions);

 

如果要对位图修改,最好做一个图形拷贝,不要直接在原位图上修改:

//创建原图的一个副本,可修改(createBitmap,有两种构造方法,一种可以修改,一种不可以),创建的是一个空白的图形。

       alterBitmap=Bitmap.createBitmap(srcBmp.getWidth()*2,srcBmp.getHeight()*2,srcBmp.getConfig());

然后修改一个位图可以分为3步:

1.准备一个画板,在上面放上准备好的空白的位图。

Canvascanvas=new Canvas(alterBitmap);

//2.准备一个画笔

Paintpaint=new Paint();

//paint.setColor(Color.BLACK);//设置画笔的默认颜色。

//3.画画

Matrixmatrix=new Matrix();

//                canvas.drawBitmap(srcBmp,matrix, paint);//Matrix指的是图片的缩放比例,直接new Matrix()是按11

/*设置缩放比例的一种方式

matrix.setValues(newfloat[]{

1,0,0,

0,0.5f,0,

0,0,1

});

 

 X=1x+0y+0z;

 Y=0x+1y+0z;

 Z=0x+0y+1z;

 

 

*/

/*

 * 设置缩放比例的另一种方式

matrix.setScale(0.5f,0.5f);

canvas.drawBitmap(srcBmp,matrix, paint);*/

/*

//图形的旋转

 

 

matrix.setRotate(180,srcBmp.getWidth()/2, srcBmp.getHeight()/2);

 

*/

 

/*

//镜子效果(照镜子)

matrix.setScale(-1.0f,1.0f);

matrix.postTranslate(srcBmp.getWidth(), 0);//x轴平移

*/

//倒影效果

matrix.setScale(1.0f,-1.0f);

matrix.postTranslate(0,srcBmp.getHeight());

canvas.drawBitmap(srcBmp,matrix, paint);

iv2.setImageBitmap(alterBitmap);//把原图的副本设置到界面上

}

 

你可能感兴趣的:(android学习日记)