Android基础知识(十)之多媒体

1 计算机表示图形的几种方式

bmp:以高质量保存,用于计算机

jpg:以良好的质量保存,用于计算机和网络

png:以高质量保存

bmp格式图片大小的计算方式:图片的总像素*每个像素的大小

【1】单色:每个像素最多可以表示2种颜色,要么是黑,要么是白,那么只需要使用长度为1的二进制位来表示,那么一个像素占1/8个byte

【2】16色:每个像素最多可以表示16种颜色,0000-1111,那么只需要使用长度为4的二进制位表示,那么一个像素占4/8 = 1/2个byte

【3】256色:每个像素最多可以表示256种颜色,00000000-11111111,那么只需要使用长度为8的二进制位来表示,那么一个像素占1个byte

【4】24位:每个像素最多可以表示1600多万中颜色,RGB的组合,那么一个像素占用3个byte,R:占1个byte  G:占1个byte  B:占1个byte

Android中采用的是png格式,Android中采用ARGB格式,其中A代表透明度,Android中一个像素占4个byte


2 缩放加载大图片

09-11 21:20:22.080:I/dalvikvm-heap(2041):Forcing collection of SoftReferences for 30720012-byte allocation(申请这么大的空间,与图片实际大小没多大关系,与图片的像素有关系)

【1】获取图片分辨率  3120*4160

【2】获取手机分辨率  320*480

【3】计算缩放比  (宽除以宽,高除以高)  宽的缩放比为9.75,高的缩放比为8.667   (一般小数点后面的省略)

所以  宽:9    宽正好

          高:8    高正好


实现步骤:

【1】获取手机分辨率

//[1]获取手机的分辨率 windowmanager smsManager TelephyManager
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        //过时的方法获取分辨率
        int height = wm.getDefaultDisplay().getHeight();//获取高
        int width = wm.getDefaultDisplay().getWidth();//获取宽
        System.out.println("width:"+width+"-----"+height);
        //新的方法获取分辨率
//        Point point = new Point();
//        wm.getDefaultDisplay().getSize(point);
//        int width = point.x;
//        int height = point.y;
//        System.out.println("width:"+width+"-----"+height); 

【2】获取图片分辨率

        //创建一个位图工厂的配置参数
        BitmapFactory.Options options = new Options();
	//解码器不会真正解析位图,但是还能够提取图片的宽和高信息
	options.inJustDecodeBounds = true;
	//有时候会因为你图片太大而报错:AndroidRuntime(2041):Cause by:java.lang.OutOfMemoryError
    	BitmapFactory.decodeFile("/mnt/sdcard/picture.jpg",options);
    	//[2]获取图片的宽和高信息
    	int imgWidth = options.outWidth;
    	int imgHeight = options.outHeight;
    	System.out.println("imgWidth:"+imgWidth+"----"+imgHeight);
【3】计算缩放比

//[3]计算缩放比
    	int scale = 1;
    	int scaleX = imgWidth/width;
    	int scaleY = imgHeight/height;
    	if (scaleX > scaleY && scaleX > scale) {
			scale = scaleX;
		}if (scaleY > scaleX && scaleY > scale) {
			scale = scaleY;
		}
		System.out.println("缩放比:"+scale);

【4】按照缩放比进行显示

        //[4]按照缩放比进行显示
	options.inSampleSize = scale;
	//[5]按照缩放比进行解析位图
	options.inJustDecodeBounds = false;
	Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/picture.jpg",options);
	//[6]把bitmap显示到iv上	
    	iv.setImageBitmap(bitmap);

注意:[1]真实手机是改不了 dvm 分配的内存大小

            [2]缩放加载大图片,就是加载分辨率特别大的图片


3 创建原图的副本

为什么要创建原图的副本?因为原图不可以修改!

        //显示原图
        ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
        //显示副本
        ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
        //[1]先把tomcat.png图片转换成bitmap 显示到iv_src
        Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
        //[1.1]操作图片
        //srcBitmap.setPixel(20, 30, Color.RED);
        iv_src.setImageBitmap(srcBitmap);
        
        //[2]创建原图的副本
        //[2.1]创建一个模板 相当于创建了一个大小和原图一样的空白白纸
        Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        //[2.2]想作画 需要画笔
        Paint paint = new Paint();
        //[2.3]创建一个画布 把白纸铺到画布上
        Canvas canvas = new Canvas(copyBitmap);
        //[2.4]开始作画
        canvas.drawBitmap(srcBitmap, new Matrix(), paint);
        
        //[2.5]操作画出来的小猫照片
        for (int i = 0; i < 20; i++) {
        	copyBitmap.setPixel(20+i, 30, Color.RED);
		}
        0
        //[3]把copybitmap显示到iv_copy上
        iv_copy.setImageBitmap(copyBitmap);
        
    }

4 图形处理的API

旋转:

matrix.setRotate(20, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);
缩放:

matrix.setScale(0.5f, 0.5f);
平移:

matrix.setTranslate(30, 0);
镜面:

就是使用缩放和平移的一个组合


        matrix.setScale(-1.0f, 1);
        //postTranslate方法是上一次修改的基础上进行再次修改 setTranslate方法每次操作都是最新的,会覆盖上次的操作
        matrix.postTranslate(srcBitmap.getWidth(), 0);
倒影:

        matrix.setScale(1.0f, -1.0f);
        matrix.postTranslate(0, srcBitmap.getHeight());

5 画画板小案例

也要先创建原图的副本,然后给iv设置一个触摸事件

 iv.setOnTouchListener(new OnTouchListener() {
        	int startX = 0;
        	int startY = 0;
        	
			@Override
			public boolean onTouch(View view, MotionEvent event) {
				//获取当前事件的类型
				int action = event.getAction();
				switch (action) {
				case MotionEvent.ACTION_DOWN://按下
					System.out.println("按下");
					//获取开始位置(划线)
					startX = (int) event.getX();
					startY = (int) event.getY();
					break;
				case MotionEvent.ACTION_MOVE://移动
					System.out.println("移动");
					//获取结束位置
					int stopX = (int) event.getX();
					int stopY = (int) event.getY();
					//不停的划线
					canvas.drawLine(startX, startY, stopX, stopY, paint);
					//再次显示到IV上
					iv.setImageBitmap(copyBitmap);
					//更新一下开始坐标和结束坐标
					startX = stopX;
					startY = stopY;
					break;
				case MotionEvent.ACTION_UP://抬起
					System.out.println("抬起");
					break;
				}
				
				//True if the listener has consumes the event,false otherwise
				return true;//true:监听器处理完事件了
			}
		});
可以设置一个按钮,将画保存起来

public void click3(View v){
		/*
		 * format:格式  保存图片的格式
		 * quality:保存图片的质量
		 * SystemClock.uptimeMillis():当前手机的开机时间
		 * */
		try {
			File file = new File(Environment.getExternalStorageDirectory().getPath(),SystemClock.uptimeMillis()+".png");
			FileOutputStream fos = new FileOutputStream(file);
			copyBitmap.compress(CompressFormat.PNG, 100, fos);
			//发送一条广播 欺骗系统图库的应用
			Intent intent = new Intent();
			//设置action
			intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
			intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
			sendBroadcast(intent);
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}

6 使用MediaPlayer播放音频文件

//点击按钮 播放一个音频文件
    public void click(View v){
    	//[1]初始化MediaPlayer
    	MediaPlayer mediaPlayer = new MediaPlayer();
    	//[2]设置要播放的资源位置 path可以是网络资源 也可以是本地资源
    	try {
			mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");
			//[3]准备播放
			mediaPlayer.prepare();
			//[4]开始播放
			mediaPlayer.start();
		} catch (Exception e) {
			e.printStackTrace();
		} 
    	
}

7  MediaPlayer的生命周期

同步和异步

同步准备:一般播放本地音乐

异步准备:一般播放网络音乐,不用开子线程


8 SurfaceView介绍

播放视频

MediaPlayer只能播放mp4格式或者3gp格式

surfaceView它是一个重量级应用

内部维护了2个线程

        A线程  加载数据   A负责显示

        B线程  负责显示  B去加载数据

它可以直接在子线程中更新UI


9 VideoView控件介绍

VideoView是对SurfaceView和MediaPlayer的封装

AVI格式或者rmvb格式

布局里面:

<VideoView

       android:id="@+id/vv"

       android:layout_width="wrap_content"

             android:layout_height="wrap_content"

       />

//[1]找到控件
    VideoView vv = (VideoView) findViewById(R.id.vv);
    //[2]设置播放的路径
    vv.setVideoPath("http://192.168.177.1:8080/miss.mp4");
    vv.start();

10 vitamio框架

解码原理:使用的是一个开源项目


11照相机和录像机

//点击按钮 实现拍照
    public void click1(View v){
    	 // create Intent to take a picture and return control to the calling application
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File file = new File(Environment.getExternalStorageDirectory().getPath(),"haha.png");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // 保存图片

        // start the image capture Intent
        startActivityForResult(intent, 1);
    }
    //当开启的Activity关闭的时候调用
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	
    	System.out.println("onActivityResult");
    	super.onActivityResult(requestCode, resultCode, data);
    }
    //点击按钮 实现录影
    public void click2(View v){
    	Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        File file = new File(Environment.getExternalStorageDirectory().getPath(),"hehe.mp4");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // 保存图片

        // start the image capture Intent
        startActivityForResult(intent, 2);
    }









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值