Android13-多媒体编程

1.计算机图片的说明

1:BMP,质量最高,用于计算机。
2:PNG,质量高。用户计算机,网络,Android中的图片一般使用png保存。
3:JPEG,较高质量。用于计算机、网络、电子邮件。
4:gif,质量不好,用于计算机、网络、制作动图。
5:单色。一个像素使用一个二进制数表示。200*200单色图片。40000/8(8个二进制数1字节)=5000,5000/1024=4.8,大概是4.8kb。
6:16色。一个像素可以表示16种颜色,使用4位。所以一个像素是0.5byte。
7:256色。一个像素可以表示256中颜色。使用8位,所以一个像素就是1byte。
8:24位位图。一个像素使用24个二进制数表示,所以一个像素就是3byte。
9:Android使用argb表示,alpha代表8个二进制数,red代表8个二进制数,green代表8个二进制数,blue代表8个二进制数。所以一个像素就是4byte。

2.加载大图是遇到的问题和解决方法

public class MainActivity extends Activity {

	
    private ImageView iv_dog;
    private String path = "mnt/sdcard/dog.bmp";
	private Point outSize;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        iv_dog = (ImageView) findViewById(R.id.iv_doy);
        
        //获取屏幕的宽和高,这两个方法已经过时了
        int width = getWindowManager().getDefaultDisplay().getWidth();
        int height = getWindowManager().getDefaultDisplay().getHeight();
        System.out.println("width:" + width + "height:" + height);
        outSize = new Point();
		//采用不过时的方式过去屏幕宽和高,这种方式会将宽和高信息封装在Point中
        //同时这种方式要求最小的版本是13,
        //所以应该修改清单文件中的uses-sdk的android:minSdkVersion="13"
        getWindowManager().getDefaultDisplay().getSize(outSize);
        
        System.out.println("width:" + outSize.x + "height:" + outSize.y);
    }


    public void onClick(View v){
    	loadImg4();
    }
    
    public void loadImg1(){
    	//直接进行图片的展示,可能会出现错误
    	Bitmap bitmap = BitmapFactory.decodeFile(path);
    	iv_dog.setImageBitmap(bitmap);
    }
    
    /*
     * 图片压缩之后再进行展示
     */
    public void loadImg2(){
    	//通过Options来进行一些相关图片的操作,如压缩
    	BitmapFactory.Options options = new Options();
    	//设置压缩图片的比例,如果设置为2,则长和宽个压缩1/2,将压缩1/4
    	//如果设置的数 <=1,则按1进行处理。通过会按照2的指数进行压缩比例
    	//如果不是2的指数,则会选择一个最接近的2的指数。
    	//options.inSampleSize = 3,计算是1/9,则会按照1/8进行处理
    	options.inSampleSize = 2;
    	Bitmap bitmap = BitmapFactory.decodeFile(path,options);
    	iv_dog.setImageBitmap(bitmap);
    }
    
    /*
     * 通过计算图片和手机屏幕的宽度和高度的比列,计算压缩比例,进行图片的压缩
     */
    public void loadImg3(){
    	BitmapFactory.Options options = new Options();
    	//通过将inJustDecodeBounds设置为true,保证只是读取图片的宽、高、类型的信息
    	//保证decode方法在解析图片的时候,不会讲图片加入内存
    	options.inJustDecodeBounds = true;
    	Bitmap bitmap = BitmapFactory.decodeFile(path,options);
    	int width = options.outWidth;
    	int height = options.outHeight;
    	
    	int widthScreen = outSize.x;
    	int heightScreen = outSize.y;
    	//当图片的宽和高比屏幕大的时候进行图片的压缩
    	if(width > widthScreen || height > heightScreen){
    		int widthNum = Math.round((float)width / (float) widthScreen);
    		int heightNum = Math.round((float) height / (float) heightScreen);
    		options.inSampleSize = Math.max(widthNum, heightNum);
    	}
    	System.out.println(options.inSampleSize);
    	options.inJustDecodeBounds = false;
    	bitmap = BitmapFactory.decodeFile(path,options);
    	iv_dog.setImageBitmap(bitmap);
    }
    
    /*
     * 通过不断尝试的方法,确定压缩的比列
     */
    public void loadImg4(){
    	BitmapFactory.Options options = new Options();
    	Bitmap bitmap = null;
    	int i = 1;
		for(;;){
			try {
				options.inSampleSize = i;
				bitmap = BitmapFactory.decodeFile(path, options);
				//如果可以加就跳出循环
				break;
			} catch (Error e) {
				//图片接在失败,是因为out of memory,是一个Error所以应该用Error进行抓取
				i *= 2;
				System.out.println(i);
			}
		}
		
    	
    	iv_dog.setImageBitmap(bitmap);
    }
}

3.创建图片副本

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ImageView iv_tomcat = (ImageView) findViewById(R.id.iv_tomcat);
        //直接加载项目中的资源
        //getResources直接加载res目录对象
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
        iv_tomcat.setImageBitmap(bitmap);
        
        //从项目中直接加载到的图片是不能进行修改的,所以要创建副本
        //createBitmap创建一个副本,分别传入宽、高、图片的匹配信息,这些信息都可以从原图中获取
        Bitmap bitmap2 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
        
        //Canvas相当于画布,需要传入一个可以修改的Bitmap,所以传入刚创建的空白的Bitmap对
        Canvas canvas = new Canvas(bitmap2);
        
        Matrix matrix = new Matrix();
		Paint paint = new Paint();
		//drawBitmap方法会对照bitmap,即原图画出Bitmap,需要传入,矩阵、画笔
		//执行完这个方法,原图的内容就会画到创建的空白的图片上
		canvas.drawBitmap(bitmap, matrix, paint);
		for(int i = 0;i < 30;i++){
			bitmap2.setPixel(i, i, Color.RED);
		}
		iv_tomcat.setImageBitmap(bitmap2);
    }
}

4.图形简单处理

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ImageView iv_img2 = (ImageView) findViewById(R.id.iv_img2);
        
        //原图
        Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
        
        Bitmap bitmap2 = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig());
        Canvas canvas = new Canvas(bitmap2);
        
        Matrix matrix = new Matrix();
        //使用Matrix矩阵对Bitmap进行操作
        //setRotate,旋转,第一个参数是 旋转的度数,后两个参数是旋转的中心点
        matrix.setRotate(20, 0f, 0f);
        
        //setTranslate进行平移,参数是x、y轴平移的距离
        matrix.setTranslate(30f, 0f);
        
        //setScale进行镜像
        matrix.setScale(1f, -1f);
        //多次进行set操作会将原来的效果清除,所以要使用post
        matrix.postTranslate(0, bitmap2.getHeight());
        
		Paint paint = new Paint();
		canvas.drawBitmap(bitmap1, matrix, paint);
        
        iv_img2.setImageBitmap(bitmap2);
    }

}

5.画画板案例

public class MainActivity extends Activity {

    private Canvas canvas;
	private Paint paint;
	private ImageView iv_img;
	private Bitmap bitmap2;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        iv_img = (ImageView) findViewById(R.id.iv_img);
        
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
        bitmap2 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
        
        canvas = new Canvas(bitmap2);
        Matrix matrix = new Matrix();
		paint = new Paint();
		canvas.drawBitmap(bitmap, matrix, paint);
		
		iv_img.setImageBitmap(bitmap2);
		
		MyOnTouchListener l = new MyOnTouchListener();
		//为ImageView设置触摸的监听事件
		iv_img.setOnTouchListener(l);
    }
    
    private class MyOnTouchListener implements OnTouchListener {
    	
    	private float startX;
    	private float startY;

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			//通过getAction获取进行的操作
			//ACTION_DOWN 落下
			//ACTION_MOVE 移动
			//ACTION_UP 抬起
			int action = event.getAction();
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				startX = event.getX();
				startY = event.getY();
				break;
			case MotionEvent.ACTION_MOVE:
				float x = event.getX();
				float y = event.getY();
				//划线
				System.out.println("x" + x + "y" + y + "startX" + startX + "startY" + startY);
				canvas.drawLine(startX, startY, x, y, paint);
				//更新画面
				iv_img.setImageBitmap(bitmap2);
				startX = x;
				startY = y;
				break;
			case MotionEvent.ACTION_UP:
				System.out.println("up");
				break;
			}
			//返回值为true则表示,当前组件消费了这一系列的事件
			//这一系列的事件有 down(一次)、move(多次)、up(一次)组成
			//如果down时返回false,则会将move、up讲给父组件进行处理
			return true;
		}
    }
    
    public void changeColor(View v){
    	paint.setColor(Color.RED);
    }
    
    public void changeWidth(View v){
    	paint.setStrokeWidth(5);
    }
    
    public void save(View v){
    	//将图片保存在sd卡中
    	File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".png");
    	FileOutputStream outputStream = null;
    	System.out.println(Environment.getExternalStorageDirectory().toString());
    	try {
			outputStream = new FileOutputStream(file);
			//第一个参数保存的格式
	    	//第二个参数保存的质量 0最不好,100最好。png不受0-100的影响
	    	bitmap2.compress(CompressFormat.PNG, 100, outputStream);
	    	
	    	
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	//保存图片之后,发送sd卡挂载的广播
    	//系统受到广播之后,会扫描sd开,将新保存的文件更新到数据库
    	Intent intent = new Intent();
    	intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
    	intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
    	sendBroadcast(intent);
    	System.out.println("kkkk");
    }
}

6.syf案例

public class MainActivity extends Activity {
	
	private Bitmap bitmap2;
	private ImageView iv_front;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        iv_front = (ImageView) findViewById(R.id.iv_front);
        
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.front);
        bitmap2 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
        
        Canvas canvas = new Canvas(bitmap2);
        Matrix matrix = new Matrix();
		Paint paint = new Paint();
		canvas.drawBitmap(bitmap, matrix, paint);
		
		iv_front.setImageBitmap(bitmap2);
		iv_front.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				int action = event.getAction();
				switch (action) {
				case MotionEvent.ACTION_DOWN:
					
					break;
				case MotionEvent.ACTION_MOVE:
					float x = event.getX();
					float y = event.getY();
					//使用try-catch放出得到的x、y超出图片
					try {
						//使用两层for循环将鼠标按下去的周围图片都变为透明色
						for(int i = -5;i <= 5;i++){
							for(int j = -5;j <= 5;j++){
								//使用if,使得鼠标落下之后画一个圆,而不是正方形
								if(Math.sqrt(i * i + j* j) <= 5){
									bitmap2.setPixel((int)x + i, (int)y + j, Color.TRANSPARENT);
								}
							}
						}
						iv_front.setImageBitmap(bitmap2);
					} catch (Exception e) {
						// TODO: handle exception
					}
					break;
				case MotionEvent.ACTION_UP:
	
					break;
				}
				return true;
			}
		});
    }
    
}

7.音乐播放器

public class MainActivity extends Activity {
	
	private MyBinder myBinder;
	private ImageButton ib_play;
	private MyServiceConnection conn;
	private SeekBar sb_progress;
	//通过Handler来定时更新进度条
	private Handler handler = new Handler(){
		
		public void handleMessage(Message msg) {
			if(msg.what == UPDATE_SEEKBAR){
				updateProgress();
			}
		}
	};
	private int UPDATE_SEEKBAR = 1;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ib_play = (ImageButton) findViewById(R.id.ib_play);
        sb_progress = (SeekBar) findViewById(R.id.sb_progress);
        
        //混合是开启音乐服务
        Intent service = new Intent(this,MusicPlayService.class);
        startService(service);
        conn = new MyServiceConnection();
        bindService(service, conn, BIND_AUTO_CREATE);
        
        sb_progress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// 停止触摸SeekBar
				
			}
			
			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// 开始触摸SeekBar
				
			}
			
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				//fromUser为true说明是用户在操作进度条
				if(fromUser){
					myBinder.seekTo(progress);
				}
			}
		});
    }
    
    /**
     * 进行音乐的播放和图片的改变
     * @param v
     */
    public void play(View v){
    	//这个方法已经将音乐的状态修改
    	myBinder.playPause();
    	changeImg();
    }
    
    /**
     * 更新进度条,
     */
    public void updateProgress(){
    	System.out.println("updateProgress");
    	sb_progress.setProgress(myBinder.getCurrentPosition());
    	//发送一个延时500毫秒的消息,500后再更新SeekBar
    	handler.sendEmptyMessageDelayed(UPDATE_SEEKBAR, 500);
    }
    
    /**
     * 改变图片和进度条的状态
     */
    public void changeImg(){
    	if(myBinder.isPlaying()){
    		ib_play.setImageResource(R.drawable.btn_audio_play);
    		//如果是播放状态就每隔500毫秒更新进度条
    		handler.sendEmptyMessage(UPDATE_SEEKBAR);
    	}else {
    		ib_play.setImageResource(R.drawable.btn_audio_pause);
    		//如果是暂停状态就取消消息的发送
    		handler.removeMessages(UPDATE_SEEKBAR);
    	}
    }
    
    private class MyServiceConnection implements ServiceConnection {
    	
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			myBinder = (MyBinder) service;
			//当页面重现显示的使用,保持暂停按钮的图片和其状态相对应
			changeImg();
			
			//保持进度条的当前状态
			sb_progress.setMax(myBinder.getDuration());
			sb_progress.setProgress(myBinder.getCurrentPosition());
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
    	
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
    	//判断myBinder != null,保证在第一个创建Activity时执行这个方法不会有空指针
    	if(myBinder != null){
    		//当重新加载页面就更新进度条
    		handler.sendEmptyMessage(UPDATE_SEEKBAR);
    	}
    }
    
    @Override
    protected void onStop() {
    	super.onStop();
    	//应用在后台运行,不更新SeekBar
    	handler.removeCallbacksAndMessages(null);
    }
    
    @Override
    protected void onDestroy() {
    	unbindService(conn);
    	super.onDestroy();
    }

}

public class MusicPlayService extends Service {
	
	//音乐路径
	private String path = "mnt/sdcard/xpg.mp3";
	private MediaPlayer player;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return new MyBinder();
	}
	
	public class MyBinder extends Binder{
		
		/**
		 * 通过音乐的状态判断播放或者停止音乐
		 */
		public void playPause(){
			if(isPlaying()){
				player.pause();
			}else {
				player.start();
			}
		}
		
		public boolean isPlaying(){
			return player.isPlaying();
		}
		
		/**
		 * 获取音乐的播放的时长
		 * @return
		 */
		public int getDuration(){
			return player.getDuration();
		}
		
		/**
		 * 获取音乐当前播放的位置
		 * @return
		 */
		public int getCurrentPosition(){
			return player.getCurrentPosition();
		}
		
		/**
		 * 设置音乐的进度
		 * @param msec
		 */
		public void seekTo(int msec){
			player.seekTo(msec);
		}
	}
	
	@Override
	public void onCreate() {
		player = new MediaPlayer();
		try {
			//为MediaPlayer设置播放音乐的数据源
			player.setDataSource(path);
			//开始准备播放音乐
			player.prepare();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

8.播放网络音乐

public class MainActivity extends Activity {
	
	private String path = "http://10.0.2.2:8080/xpg.mp3";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void start(View v){
    	MediaPlayer player = new MediaPlayer();
    	
    	try {
			player.setDataSource(path);
			//播放网络音乐,采用异步的方式进行
			player.prepareAsync();
			player.setOnPreparedListener(new OnPreparedListener() {
				
				/**
				 * 当准备好了就会执行onPrepared,mp就是当前MediaPlayer对象
				 */
				@Override
				public void onPrepared(MediaPlayer mp) {
					//
					mp.start();
				}
			});
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
}

9.SurfaceView和Mediaplayer播放视频

1:SurfaceView是一个重量级的空间,加载需要时间。他主要进行数据的展示,使用SurfaceHolder控制数据的展示。SurfaceView可以用来展示频繁变化的界面。
2:Mediaplayer音频的播放和音视频的解码。
public class MainActivity extends Activity {
	
	private String path = "http://10.0.2.2:8080/oppo.mp4";
	private SurfaceHolder holder;
	private MediaPlayer player;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        SurfaceView sv_video = (SurfaceView) findViewById(R.id.sv_video);
        holder = sv_video.getHolder();
    }

    public void start(View v){
    	player = new MediaPlayer();
    	try {
			player.setDataSource(path);
			player.prepareAsync();
			//设置MediaPlayer显示的空间
			player.setDisplay(holder);
			player.setOnPreparedListener(new OnPreparedListener() {
				
				@Override
				public void onPrepared(MediaPlayer mp) {
					mp.start();
				}
			});
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void pause(View v){
    	if(player != null){
    		if(player.isPlaying()){
    			player.pause();
    		}else {
    			player.start();
    		}
    	}
    }
}

10.VideoView播放视频

public class MainActivity extends Activity {
	
	private String path = "http://10.0.2.2:8080/oppo.mp4";
	private VideoView vv_video;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        vv_video = (VideoView) findViewById(R.id.vv_video);
    }

    public void start(View v){
    	//这个方法会设置路径、创建MediaPlayer对象、prepareAsync异步准备
    	vv_video.setVideoPath(path);
    	vv_video.setOnPreparedListener(new OnPreparedListener() {
			
			@Override
			public void onPrepared(MediaPlayer mp) {
				mp.start();
			}
		});
    	
    	vv_video.setMediaController(new MediaController(this));
    }
    
    public void pause(View v){
    	
    }
}

11.libary的导入和使用

1:import -> Browse -> Copy projects into workspece。
2:当前项目 -> Properties -> Android -> add -> 选择要的libary。

12.vitamio的使用

1:以library的形式引入vitamio框架。
2:在布局中定义VideoView
<io.vov.vitamio.widget.VideoView 
	android:id="@+id/vv"
	android:layout_width="match_parent"
	android:layout_height="match_parent" />
3:插件vitamio框架检查是否可用
if (!LibsChecker.checkVitamioLibs(this)) {
	return;
}
4:一定要在清单文件初始化InitActivity。 <activity android:name="io.vov.vitamio.activity.InitActivity"></activity>。
public class MainActivity extends Activity {
	
	private String path = "http://10.0.2.2:8080/rmvb.rmvb";
	private VideoView vv_video;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!LibsChecker.checkVitamioLibs(this)) {
			return;
		}
        setContentView(R.layout.activity_main);
        
        vv_video = (VideoView) findViewById(R.id.vv_video);
    }

    public void start(View v){
    	//这个方法会设置路径、创建MediaPlayer对象、prepareAsync异步准备
    	vv_video.setVideoPath(path);
    	vv_video.setOnPreparedListener(new OnPreparedListener() {
			
			@Override
			public void onPrepared(MediaPlayer mp) {
				mp.start();
			}
		});
    	
    	vv_video.setMediaController(new MediaController(this));
    }
    
    public void pause(View v){
    	
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值