计算机表示图形的方式

bmp 以高质量保存所有类型的图片,用于计算机。


计算机使用像素点表示图形,每个像素点都是一个颜色,24位深度(24bit)。


        每个像素点的颜色是一个RGB,使用6个十六进制的数值来表示。


        文件头信息占用的数据大小。  体积比较大。


jpg 以良好的质量保存图片,用于计算机、电子邮件或网络。

      jpg 工业图形的压缩算法(失真),类似rar的算法。人眼识别精度有限,把相邻空间内类似的颜色使用同一个颜色来表示。 体积减小,失真。


png 以高质量保存图片或者绘图,用于计算机或网络。


不失真压缩算法,体积减小



加载大图片的OOM异常

java.lang.OutOfMemoryError : 



   堆内存空间:给类实例、数组分配内存空间的。   

RGB 24

 ARGB 32 



   应用程序在启动时系统为它创建一个进程,系统为每个进程创建dalvik虚拟机(模拟器设置的VM Heap),当图片的大小大于虚拟机的堆内存空间时,就内存溢出(内存泄露);


  解决办法:缩放图片加载到内存


  步骤:


   1、获得设备屏幕的分辨率;


   2、得到原图的分辨率;


   3、通过比较得到一个合适的比例值;


   4、按照比例值缩放图片


   5、把图片显示在imageview



缩放图片并加载到内存中

步骤:


  1、获得设备屏幕的分辨率;


  2、得到原图的分辨率;


  3、通过比较得到一个合适的比例值;


  4、按照比例值缩放图片


  5、把图片显示在imageview


 代码:

package com.itheima.loadbigpic;
	
	import android.app.Activity;
	import android.graphics.Bitmap;
	import android.graphics.BitmapFactory;
	import android.graphics.BitmapFactory.Options;
	import android.os.Bundle;
	import android.os.Environment;
	import android.view.Display;
	import android.view.WindowManager;
	import android.widget.ImageView;
	
	public class MainActivity extends Activity {


	private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        iv = (ImageView) findViewById(R.id.iv);
        
	//        1、获得设备屏幕的分辨率;
        //通过服务获得窗口管理器
        WindowManager  wm =  (WindowManager) getSystemService(WINDOW_SERVICE);
        //获得设备分辨率对象
        Display display = wm.getDefaultDisplay();
        
        //api13之前使用这个两个方法,13之后置为过期
        int screenWidth = display.getWidth();
        int screenHeight = display.getHeight();
        
        
	//        2、得到原图的分辨率;
       
        Options opts = new Options();
        opts.inJustDecodeBounds = true;
        //opts为null 可以返回一个图片对象,如果不为null ,就会返回null
        BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/lp.jpg", opts);
        //得到原图的宽和高
         int srcWidth = opts.outWidth;
         int srcHeight = opts.outHeight;
         
         
	//        3、通过比较得到一个合适的比例值;
         //3000/320 = 9 2262/480 =5
         int sx = srcWidth/screenWidth;
         int sy = srcHeight/screenHeight;
         int scale = 0;
         if(sx >= 1 && sx > sy){
        	 scale = sx;
         }else if(sy >= 1 && sy > sx){
        	 scale = sy;
         }
         
	//     4、按照比例值缩放图片
           opts.inJustDecodeBounds = false;
           opts.inSampleSize = scale; // 1/scale * 1/scale
           Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/lp.jpg", opts);
          
	//    5、把图片显示在imageview
           
           iv.setImageBitmap(bm);
    }
	
	}

内存空间创建一个原图的副本

步骤


//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 


Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());




//2 我要往白纸画画  需要画笔 


Paint paint = new Paint();   //创建一个画笔 


//3 需要一个画布  拿到一个画布    把纸铺到画布上 


Canvas canvas = new Canvas(copybBitmap);


//4 开始作画    bitmap :参考谁去画    matrix 矩阵


canvas.drawBitmap(srcBitmap, new Matrix(), paint);


copybBitmap.setPixel(10, 20, Color.RED);


//5 把拷贝的副本显示到  copyimageview上 


iv_copy.setImageBitmap(copybBitmap);

代码

package com.itheima.copypic;

	import android.app.Activity;
	import android.graphics.Bitmap;
	import android.graphics.BitmapFactory;
	import android.graphics.Canvas;
	import android.graphics.Color;
	import android.graphics.Matrix;
	import android.graphics.Paint;
	import android.os.Bundle;
	import android.widget.ImageView;
	
	public class MainActivity extends Activity {

	private ImageView iv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		iv = (ImageView) findViewById(R.id.iv);
		
		
	//		   1、得到原图;
		    Bitmap srcPic = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);
		    
		    //config 包括位深度
	//		   2、创建一个空白的纸张,参考原图;
		   Bitmap copyPic = Bitmap.createBitmap(srcPic.getWidth(), srcPic.getHeight(), srcPic.getConfig());	
	//		   3、创建一个画板,参考空白纸张;
		   Canvas canvas = new Canvas(copyPic);
		   
	//		   4、创建一个画笔;
		   Paint paint = new Paint();
		   paint.setColor(Color.BLACK);//默认是使用黑色,后面会根据原图的颜色画画
	//		   5、在画板上画画;
		   canvas.drawBitmap(srcPic, new Matrix(), paint);
		   
		   iv.setImageBitmap(copyPic);
	}


	}

计算机图形处理的常用API

旋转

public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth()+40, srcBitmap.getHeight(), srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
		Matrix matrix = new Matrix();
		// 图形的旋转操作   旋转30
//		matrix.setRotate(30);
		matrix.setRotate(30, copybBitmap.getWidth()/2,copybBitmap.getHeight()/2);
		canvas.drawBitmap(srcBitmap, matrix, paint);
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);	
		
	}

	

}

缩放


public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth()*2, srcBitmap.getHeight()*2, srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
		Matrix matrix = new Matrix();
		// 图形的缩放处理 
		matrix.setScale(2, 2);
		
		canvas.drawBitmap(srcBitmap, matrix, paint);
		
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);
		
		
		
		
		
		
	}

	

}





平移

public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth()+40, srcBitmap.getHeight(), srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
		Matrix matrix = new Matrix();
		// 图形的平移
		matrix.setTranslate(20, 20);
		
		canvas.drawBitmap(srcBitmap, matrix, paint);
		
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);
		
		
		
		
		
		
	}

	

}

镜面

public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
		Matrix matrix = new Matrix();
		// 图形的镜面效果
		matrix.setScale(-1.0f, 1.0f);
		matrix.postTranslate(copybBitmap.getWidth(), 0);
		
		canvas.drawBitmap(srcBitmap, matrix, paint);
		
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);
		
		
		
	}

	

}

倒影


public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
		Matrix matrix = new Matrix();
		// 图形的倒影效果
		matrix.setScale(1.0f, -1.0f);
		matrix.postTranslate(0, srcBitmap.getHeight());
		
		canvas.drawBitmap(srcBitmap, matrix, paint);
		
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);
		
		
		
		
		
		
	}

	

}


修改颜色


public class MainActivity extends Activity {

	@SuppressLint("SdCardPath")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//找到我们关心的2个imageview
		ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
		ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
		
		//显示原图
		//获取到原图的bitmap   他是只读的不可以被修改 
		Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.png");
		
		
		iv_src.setImageBitmap(srcBitmap);
		
		//1我要创建原图的副本   他只是一个空的bitmap    理解成是一张白纸 
		Bitmap copybBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
		
		
		//2 我要往白纸画画  需要画笔 
		Paint paint = new Paint();   //创建一个画笔 
		
		//3 需要一个画布  拿到一个画布    把纸铺到画布上 
		Canvas canvas = new Canvas(copybBitmap);
		//4 开始作画    bitmap :参考谁去画    matrix 矩阵
		
	
		
		ColorMatrix cm = new ColorMatrix(); //创建一个颜色的矩阵
		cm.set(new float[] {
		2, 0, 0, 0, 0,
		0, 1, 0, 0, 0,
		0, 0, 1, 0, 0,
		0, 0, 0, 1, 0
		});
		paint.setColorFilter(new ColorMatrixColorFilter(cm));
		
		/**
		        New Red Value = 1*128 + 0*128 + 0*128 + 0*0 + 0
				New Blue Value = 0*128 + 1*128 + 0*128 + 0*0 + 0
				New Green Value = 0*128 + 0*128 + 1*128 + 0*0 + 0
				New Alpha Value = 0*128 + 0*128 + 0*128 + 1*0 + 0
				*/
		
		
		canvas.drawBitmap(srcBitmap, new Matrix(), paint);
		
		
		//5 把拷贝的副本显示到  copyimageview上 
		iv_copy.setImageBitmap(copybBitmap);
		
		
		
		
		
		
	}

	

}

实例代码:画画板



package com.itheima.painter;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView iv;
	private Bitmap srcPic;
	private Bitmap copyPic;
	private Canvas canvas;
	private Paint paint;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		
		iv  = (ImageView) findViewById(R.id.iv);
		
		
		
		srcPic = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
				    
		copyPic = Bitmap.createBitmap(srcPic.getWidth(), srcPic.getHeight(), srcPic.getConfig());
		canvas = new Canvas(copyPic);
				   
		paint = new Paint();
				   paint.setColor(Color.BLACK);//默认是使用黑色,后面会根据原图的颜色画画
	//				   5、在画板上画画;
				   
				   Matrix matrix = new Matrix();
	//				   
				   canvas.drawBitmap(srcPic, matrix, paint);
				   iv.setImageBitmap(copyPic);
				   
				   iv.setOnTouchListener(new OnTouchListener(){
					   int startX ;
					   int startY;
					@Override
					public boolean onTouch(View v, MotionEvent event) {
						int type = event.getAction();
						
						
						switch (type) {
						case MotionEvent.ACTION_DOWN:
							
							//开始坐标点
							 startX = (int) event.getX();
							
							 startY = (int) event.getY();
							
							break;

						case MotionEvent.ACTION_MOVE :
							
							//得到结束点的坐标
							int newX = (int) event.getX();
							int newY = (int) event.getY();
							
							canvas.drawLine(startX, startY, newX, newY, paint);
							
							iv.setImageBitmap(copyPic);
							
							//得到新的开始坐标点
							 startX = (int) event.getX();
							
							 startY = (int) event.getY();
							break;
						}
						
						//消费掉当前的监听器
						return true;
					}
					   
				   });
				   
	}

	

	}