Android核心基础第八天

本文详细介绍了Android应用开发过程中的关键技术和实例,包括图片处理、多媒体操作、内存管理、事件响应、界面交互等核心模块。通过具体案例,如快图浏览、大图片处理、内存优化、视频播放、音乐播放、相机使用等,深入浅出地阐述了各部分的实现细节与优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、学习目标及要求

课程目标

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

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

* 掌握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();

  

  
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();

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();


  
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();

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();

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>

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/loveandroid/p/3767661.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值