一、学习目标及要求
课程内容(必须讲的内容,就是讲课的知识点的顺序) * 掌握从系统获取一张图片
* 掌握android下大图片处理
* 掌握画笔 画布
* 熟悉触摸事件
* 掌握图片旋转 缩放 平移 倒影
* 掌握图片饱和度 颜色的处理
* 掌握图片的合成
* 了解人脸识别的原理
* 掌握mediaplayer的使用
* 掌握soundpool的使用
* 掌握mediaplayer的生命周期
* 掌握视频播放
* 掌握在线视频的播放
* 掌握音乐播放
* 掌握android照相机的使用
* 掌握从系统获取一张图片 案例: 快图浏览, 选择查看图片
* 掌握android下大图片的处理 案例: 3M的数码相机图片的处理
* 掌握内存溢出的处理 案例: 内存优化
* 掌握画笔 画布 案例: 图片画画板
* 熟悉触摸事件
触摸事件 触摸 移动 离开
* 掌握图片的旋转 缩放 平移 倒影
* 掌握mediaplayer的使用
* 掌握mediaplayer的生命周期
Start -> prepare - > start ->seekto ->release
* 掌握surfaceview的生命周期 创建和销毁的时机
* 掌握视频播放 案例: 视频播放器
* 掌握在线视频的播放 在线播放视频
* 掌握音乐播放 案例: 音乐播放器
* 掌握android照相机的使用 案例: 照相机
二、学习要点
1. 从系统图库获取一张图片
1.1 实现效果
/**
* 开启系统图库获取返回值*/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);}/**
* 取返回值*/@Overrideprotected 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 实现效果
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;// 真正的解析bitmapopts.inSampleSize = scale;// 指定图片缩放比例
bitmap = BitmapFactory.decodeFile(path, opts);return bitmap;
};
3. 创建图片内存拷贝
3.1 原始图片效果
//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 镜子效果
//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();
canvas.drawBitmap(bitmap,matrix , paint);iv_dest.setImageBitmap(alterbitmap);
3.3 放大缩小
//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();
canvas.drawBitmap(bitmap,matrix , paint);iv_dest.setImageBitmap(alterbitmap);
3.4 倒影效果
//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();
canvas.drawBitmap(bitmap,matrix , paint);iv_dest.setImageBitmap(alterbitmap);
3.5 图片旋转
//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();
canvas.drawBitmap(bitmap,matrix , paint);iv_dest.setImageBitmap(alterbitmap);
3.6 图片的位移
//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();
canvas.drawBitmap(bitmap,matrix , paint);iv_dest.setImageBitmap(alterbitmap);
4. 邪恶小游戏 撕衣服
4.1 预览效果
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;
@Overrideprotected 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() {
@Overridepublic 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" ><ImageViewandroid: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" /><ImageViewandroid:id="@+id/iv_pre"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true" /></RelativeLayout>