• 安卓基础干货(十):安卓多媒体编程的学习


    多媒体编程

    1、什么是多媒体?

    多种媒体的综合。图片、音乐、视频。

    计算机表示图形的方式

    1、bmp 以高质量保存所有类型的图片,用于计算机。
    	计算机使用像素点表示图形,每个像素点都是一个颜色,24位深度(24bit)。
    	每个像素点的颜色是一个RGB,使用6个十六进制的数值来表示。
    	文件头信息占用的数据大小。  体积比较大。
    
    2、jpg 以良好的质量保存图片,用于计算机、电子邮件或网络。
    	jpg 工业图形的压缩算法,类似rar的算法。人眼识别精度有限,把相邻空间内类似的颜色使用同一个颜色来表示。 体积减小,失真。
    	
    3、png 203.2k 255*340 以高质量保存图片或者绘图,用于计算机或网络。
    

    加载大图片的OOM异常

    java.lang.OutOfMemoryError : 
    

    堆内存空间:给类实例、数组分配内存空间的。 RGB
    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、得到原图;
       2、创建一个空白的纸张,参考原图;
       3、创建一个画板,参考空白纸张;
       4、创建一个画笔;
       5、在画板上画画;
    

    代码:

    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(重点)

    * 旋转
    * 缩放
    * 平移
    * 镜面、倒影
    * 修改颜色
    ColorMatrix cm = new ColorMatrix();
    	cm.set(new float[] {
    			1, 0, 0, 0, 0,  //red
    			0, 1, 0, 0, 0,  //green
    			0, 0, 1, 0, 0,  //blue
    			0, 0, 0, 1, 0   //透明度
    	});
    	paint.setColorFilter(new ColorMatrixColorFilter(cm));
    

    微信画画板

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

    视频播放器videoview(重点)

    代码:

    package com.itheima.videoview;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.VideoView;
    
    public class MainActivity extends Activity {
    
    	private VideoView vv;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		vv = (VideoView) findViewById(R.id.vv);
    		
    		vv.setVideoPath("http://192.168.22.136:8080/11.mp4");
    		
    		vv.start();
    		
    		
    	}
    
    
    }
    

    视频播放器surfaceview(重点)

    surfaceview表面视图

    双缓冲区:使用两个线程协调工作;

    surfaceview 重量级空间,当画面可见时,双缓冲器被创建,占用较高的cpu和内存资源。

    当界面不可见时,双缓冲器占用释放。

    音乐播放器API

    package com.itheima.surfaceview;
    
    import android.app.Activity;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.os.Bundle;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    
    public class MainActivity extends Activity {
    
    	private SurfaceView sv;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		sv = (SurfaceView) findViewById(R.id.sv);
    		
    		SurfaceHolder holder = sv.getHolder();
    		//推送缓冲数据,api 13之前的版本上必须执行这行代码,13版本之后,播放器可以自动把
    		//数据加载到缓冲区
    		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    	
    		holder.addCallback(new Callback() {
    			
    			private MediaPlayer mediaPlay;
    
    			@Override
    			public void surfaceCreated(SurfaceHolder holder) {
    				try {
    					mediaPlay = new MediaPlayer();
    					
    					mediaPlay.setDataSource("http://192.168.22.136:8080/11.mp4");
    					mediaPlay.setAudioStreamType(AudioManager.STREAM_MUSIC);
    					
    					mediaPlay.setDisplay(holder);
    					
    					//使用阻塞式准备方法,等待数据资源准备完成后才开始播放,用于播放本地的音视频文件
    //					mediaPlay.prepare(); 
    					//使用异步式准备方法,使用子线程等待数据资源准备完成后才开始播放,用于播放网络上的音视频文件
    					mediaPlay.prepareAsync();
    					
    					mediaPlay.setOnPreparedListener(new OnPreparedListener() {
    						
    						@Override
    						public void onPrepared(MediaPlayer mp) {
    							
    							mediaPlay.start();
    						}
    					});
    					
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    				
    			}
    			
    			@Override
    			public void surfaceDestroyed(SurfaceHolder holder) {
    				if(mediaPlay != null && mediaPlay.isPlaying()){
    					mediaPlay.stop();
    					
    					mediaPlay.release();
    					
    					mediaPlay = null;
    					
    //					mediaPlay.seekTo(msec);
    					
    				}
    			}		
    			
    			@Override
    			public void surfaceChanged(SurfaceHolder holder, int format, int width,
    					int height) {
    				// TODO Auto-generated method stub
    				
    			}
    		});
    	}
    }		
    

    vitamio框架的使用

    1 引入vitamio框架 以library形式引入

    2 在布局中定义VideoView

    <io.vov.vitamio.widget.VideoView
    android:id="@+id/vv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

    3 mainactivity代码

    插件vitamio框架检查是否可用
    if (!LibsChecker.checkVitamioLibs(this)) {
    return;
    }

    final VideoView vv = (VideoView) findViewById(R.id.vv);
    vv.setVideoPath("http://192.168.1.1:8080/haha.avi");
    vv.setOnPreparedListener(new OnPreparedListener() {
    	
    	@Override
    	public void onPrepared(MediaPlayer mp) {
    		vv.start();
    		
    	}
    });
    //设置video的控制器
    vv.setMediaController(new MediaController(this));
    

    4 一定要在清单文件初始化InitActivity

    <activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
    

    照相机拍照

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    
    file = new File(Environment.getExternalStorageDirectory()+"/123.jpg");
    
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
    
    startActivityForResult(intent, 0);
    

    录机应用

    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 
    
    file = new File(Environment.getExternalStorageDirectory()+"/123.3gp");
    
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
    
    startActivityForResult(intent, 0);
  • 相关阅读:
    全局变量与全局静态变量的区别:
    Python模块学习 ---- datetime
    python sys.path用法
    过来人谈《去360还是留在百度?》
    [编码问题] Python错误: SyntaxError: Non-ASCII character
    E513: write error, conversion failed (make 'fenc' empty to override)"解决办法
    巴真的点评
    set之hashset与TreeSet、LinkedHashSet实现原理
    list之linedlist与arraylist实现原理
    统一会话与单点登录
  • 原文地址:https://www.cnblogs.com/fanchcho/p/9233987.html
Copyright © 2020-2023  润新知