Android Lover
一个对android充满激情的小白!!!

一、学习目标及要求

课程目标

课程内容(必须讲的内容,就是讲课的知识点的顺序)

* 掌握从系统获取一张图片

* 掌握android下大图片处理

* 掌握画笔 画布

* 熟悉触摸事件

* 掌握图片旋转 缩放 平移 倒影

* 掌握图片饱和度 颜色的处理

* 掌握图片的合成

* 了解人脸识别的原理

* 掌握mediaplayer的使用

* 掌握soundpool的使用

* 掌握mediaplayer的生命周期

* 掌握视频播放

* 掌握在线视频的播放

* 掌握音乐播放

* 掌握android照相机的使用

* 掌握从系统获取一张图片    案例: 快图浏览, 选择查看图片

* 掌握android下大图片的处理    案例: 3M的数码相机图片的处理

* 掌握内存溢出的处理    案例: 内存优化

* 掌握画笔 画布     案例: 图片画画板

* 熟悉触摸事件

触摸事件 触摸 移动 离开

* 掌握图片的旋转 缩放 平移 倒影

* 掌握mediaplayer的使用

* 掌握mediaplayer的生命周期

Start -> prepare - > start ->seekto ->release

* 掌握surfaceview的生命周期    创建和销毁的时机

* 掌握视频播放    案例: 视频播放器

* 掌握在线视频的播放    在线播放视频

* 掌握音乐播放    案例: 音乐播放器

* 掌握android照相机的使用   案例: 照相机

二、学习要点

1. 从系统图库获取一张图片

1.1 实现效果

image image image

/**
 * 开启系统图库获取返回值
 */
public void click(View view){
    //打开系统的图库从里面选择一张照片
    Intent intent = new Intent();
    intent.setAction("android.intent.action.PICK");
    intent.addCategory("android.intent.category.DEFAULT");
    intent.setType("image/*");
    startActivityForResult(intent, 0);
}
/**
 * 取返回值
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(data!=null){
    //如果图片很小在内存中占用的大小小于100K 直接返回bitmap对象。
    Bitmap bitmap = data.getParcelableExtra("data");
    iv.setImageBitmap(bitmap);
    //如果图片很大,返回的只是图片的uri
    Uri uri = data.getData();
    iv.setImageURI(uri);
    }
    super.onActivityResult(requestCode, resultCode, data);
}

2. 加载大图片内存溢出问题

android系统里面每个应用程序默认的vm虚拟机最大的heap空间 16M,如果应用程序占用的内存空间超过了16M OOM(out of memory)内存溢出。

bmp jpg 图片的格式 存储方式。

问题:如何解决?
      手机屏幕的分辨率要比图片的分辨率小很多。 只需要根据手机的分辨率把图片给压缩采样,加载到手机上就行了。

步骤:

1. 计算手机屏幕的宽高
2. 计算图片的宽高
3. 计算图片的缩放比例
4. opts.inSampleSize = scale; 设置图片的缩放比例
5. 加载图片到内存

2.1 实现效果

 image image  image

2.2 核心代码

/**
 * 监听按钮的点击事件
 * @param view
 */
public void click(View view) {
    String path = "/sdcard/1.jpg";
    Bitmap bitmap = loadBigImage(path);
    iv.setImageBitmap(bitmap);
}
/**
 * 得到按照比例缩放的大图片到内存
 * 
 * @author zwenkai
 * @param path 图片路径
 * @return Bitmap 按比例缩放的图片
 */
private Bitmap loadBigImage(String path) {    
    // 1.得到手机的分辨率
    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
    // 2.得到图片的宽高属性
    Options opts = new Options();// 设置为解析图片参数
    opts.inJustDecodeBounds = true; // 只获得图片的宽高信息
    Bitmap bitmap = BitmapFactory.decodeFile(path, opts);
    int imageHeight = opts.outHeight;
    int imageWidth = opts.outWidth;
    // 3.计算缩放比比例
    int dx = imageWidth / screenWidth;
    int dy = imageHeight / screenHeight;
    System.out.println("手机分辨率:" + screenWidth + "x" + screenHeight);
    System.out.println("图片分辨率:" + imageWidth + "x" + imageHeight);
    System.out.println("缩放比例:dx=" + dx + ",dy=" + dy);
    int scale = 1;//默认缩放比为1,只有大于屏幕才缩小
    if (dx >= dy && dy >= 1) {
    	scale = dx;
    } else if (dy >= dx && dx >= 1) {
        scale = dy;
    }
    System.out.println("总体缩放比例:" + scale);
    // 加载按照屏幕缩放的图片
    opts.inJustDecodeBounds = false;// 真正的解析bitmap
    opts.inSampleSize = scale;// 指定图片缩放比例
    bitmap = BitmapFactory.decodeFile(path, opts);
    return bitmap;
};

3.  创建图片内存拷贝

3.1 原始图片效果

    image  

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
// 4.第一个参数是临摹的图片
canvas.drawBitmap(bitmap, new Matrix(), paint);
iv_dest.setImageBitmap(alterbitmap);

3.2 镜子效果 

    image

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
//	4.第一个参数是临摹的图片
// matrix  变形矩阵
Matrix matrix = new Matrix();
matrix.setScale(-1.0f, 1);
matrix.postTranslate(bitmap.getWidth(), 0);
canvas.drawBitmap(bitmap,matrix , paint);
iv_dest.setImageBitmap(alterbitmap);

3.3 放大缩小

    image

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth()*2, bitmap.getHeight()*2, bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
// 4.第一个参数是临摹的图片
// matrix  缩放矩阵
Matrix matrix = new Matrix();
matrix.setScale(1.5f, 1.5f);
canvas.drawBitmap(bitmap,matrix , paint);
iv_dest.setImageBitmap(alterbitmap);

  3.4 倒影效果

    image

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
// 4.第一个参数是临摹的图片
// matrix  变形矩阵
Matrix matrix = new Matrix();
matrix.setScale(1.0f, -1.0f);
matrix.postTranslate(0, bitmap.getHeight());
canvas.drawBitmap(bitmap,matrix , paint);
iv_dest.setImageBitmap(alterbitmap);

3.5 图片旋转

     image

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
// 4.第一个参数是临摹的图片
// matrix  变形矩阵
Matrix matrix = new Matrix();
matrix.setRotate(180 ,bitmap.getWidth()/2, bitmap.getHeight()/2);
canvas.drawBitmap(bitmap,matrix , paint);
iv_dest.setImageBitmap(alterbitmap);

3.6 图片的位移

    image

//src加载的是原图
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/6.jpg");
iv_src.setImageBitmap(bitmap);
//dest加载原图的内存拷贝
//1.按照原图的宽高和配置创建了一个一模一样的空白图片。
Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
//2.赶紧临摹一个图片
Canvas canvas = new Canvas(alterbitmap);//2.创建一个画板。构造方法传递空白的图片,按照空白图片的尺寸创建画板。
Paint paint = new Paint();//3.创建一个画笔。
paint.setColor(Color.BLACK);
// 4.第一个参数是临摹的图片
// matrix  变形矩阵
Matrix matrix = new Matrix();
matrix.setTranslate(100, 0);
canvas.drawBitmap(bitmap,matrix , paint);
iv_dest.setImageBitmap(alterbitmap);

4. 邪恶小游戏 撕衣服

4.1 预览效果

    image image

4.2 原理说明

布局为相对布局的叠加两张图片,after为xml布局中设置,pre通过内存拷贝的方式加载到Activity,并给ImageView设置监听事件setOnTouchListener,当监听到手指在屏幕移动 MotionEvent.ACTION_MOVE 后将该像素附近区域设置为透明。

4.3 知识点

拷贝图片到内存,该事例中尚未涉及到大图片到内存的情况。

手指的在屏幕移动的监听事件 setOnTouchListener,注意滑屏跳转的广泛应用。

4.4 代码清单

public class MainActivity extends Activity {
    private Bitmap alterbitmap;
    private ImageView iv_pre;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	iv_pre = (ImageView) findViewById(R.id.iv_pre);
	// 把pre的图片副本添加到桌面
	Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.pre3);
	alterbitmap = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), bitmap.getConfig());
	Canvas canvas = new Canvas(alterbitmap);
	Paint paint = new Paint();// 创建一个画笔。
	paint.setColor(Color.BLACK);// 如果原图没颜色 就默认用黑色
	canvas.drawBitmap(bitmap, new Matrix(), paint);
	iv_pre.setImageBitmap(alterbitmap);
	// 给ImageView设置触摸监听事件
	iv_pre.setOnTouchListener(new OnTouchListener() {
	    @Override
	    public boolean onTouch(View v, MotionEvent event) {
		try {
		    switch (event.getAction()) {
		    case MotionEvent.ACTION_DOWN:// 手指触摸到屏幕
			System.out.println("触摸到");
			break;
		    case MotionEvent.ACTION_MOVE:// 手指在屏幕移动
			System.out.println("移动" + event.getX() + "," + event.getY());
			int changeX = (int) event.getX();
			int changeY = (int) event.getY();
			for (int i = -5; i < 6; i++) {
			    for (int j = -5; j < 6; j++) {
				if (Math.sqrt(i * i + j * j) <= 5) {
				    alterbitmap.setPixel(changeX + i, changeY + j,Color.TRANSPARENT);
				}
			    }
			}
			iv_pre.setImageBitmap(alterbitmap);
			break;
			case MotionEvent.ACTION_UP:// 手指离开屏幕
			    System.out.println("离开");
			    break;
			}
		    } catch (Exception e) {
			e.printStackTrace();
		    }
		return true;
	    }
	});
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <ImageView
        android:id="@+id/iv_after"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/after3" />
    <ImageView
        android:id="@+id/iv_pre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />
</RelativeLayout>

 

 

 

 

 

 

 

 

 

 

 

posted on 2014-06-04 13:05  zwenkai  阅读(442)  评论(0)    收藏  举报