多媒体编程

1、什么是多媒体?   

多种媒体的综合。   

图片、音乐、视频等;

##图片的常见格式:

1.bmp:以高质量保存所有类型的图片,并将其应用于计算机;    

255 KB,255*340像素,24位深度   

计算机表示图形的时候时候是使用像素点来表示的,每个像素点都有一个颜色,每个颜色都是使用6位16进制的数值来表示的,一个像素点使用24个bit表示。          

图像大小的计算公式:分辨率的宽*高*位深度 + 头文件占用的数据大小=图形实际大小 ,颜色不会失真,图片的体积比较大。   

2.jpg:36.4 KB,255*340像素,24位深度    

jpg是一种图像工业压缩算法,类似于RAR压缩算法。人眼的识别精度是有限的,jpg把人言无法识别的颜色值压缩掉了。

计算机会使用同一种颜色来表示相邻空间内的颜色。颜色失真,图片的体积小。   

3.png:203 KB,255*340像素,32位深度            

png 是一种图像工业压缩算法,使用类似于map的数据结构表示图形。颜色不会失真,图片的体积比较小。    

2.加载大图片的OOM异常

 Out of memory on a 24753780-byte allocation. 23.6m

 java.lang.OutOfMemoryError(OOM):内存溢出、内存泄露。    

原因:当应用程序一启动的时候,系统就会创建一个dalvik虚拟机运行应用程序,应用程序加载一张图片的时候占用的内存空间就是使用堆内存空间来分配的。当图片占用的内存空间大于堆内存空间的时候就抛出内存溢出的异常。    

RGB三原色,Android表示图形的时候也可以表示透明度#ARGB   

3.缩放图片并加载到内存中

 解决办法:缩放图片。

缩放图片加载到内存步骤:

1.得到设备屏幕的分辨率的宽和高:        

2.得到原图的分辨率的宽和高:        

3.通过比较得到一个合适的比例值:        

4.根据比例值缩放原图,得到一张小图:        

5.把小图显示在imageview上:

模版代码:   

//1.得到设备屏幕的分辨率的宽和高:       
//得到系统提供的屏幕管理服务对象       
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);       
//得到默认分辨率对象       
Display display = wm.getDefaultDisplay();       
//得到屏幕的宽和高       
int screenWidth = display.getWidth();       
int screeHeigth = display.getHeight();   
//2、得到原图的分辨率的宽和高:       
Options opts = new Options();       
opts.inJustDecodeBounds = true;       
BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/1.jpg", opts);              
//得到原图的宽和高       
int srcWidth = opts.outWidth;       
int srcHeigth = opts.outHeight;   
//3、通过比较得到一个合适的比例值:       
int scale = 1;       
// width:3000/320=9,3000/480=6       
int sx = srcWidth/screenWidth;       
int sy = srcHeigth/screeHeigth;              
if(sx>=sy && sx>=1){        
scale = sx;       
}       
if(sy>=sx && sy>=1){        
scale = sy;       
}  
//

   

4、根据比例值缩放原图,得到一张小图:       

opts.inJustDecodeBounds = false;       
//按照一定的比例值缩放图片,宽和高都是原图的1/scale       
opts.inSampleSize = scale;       
Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/1.jpg", opts);         
//

5、把小图显示在imageview上:       

iv.setImageBitmap(bm);

4.在内存中创建原图的副本(重点)

 Android应用程序中不允许修改原图,所以在加载原图的时候需要在内存中创建一个与原图一模一样的副本,后面处理图形的时候只能修改副本。

 在内存中创建原图副本(临摹画画)的步骤:  

1.创建一个原图:    

2.参考原图创建一个空白纸张:    

3.创建一个画板:    

4.创建一支画笔:    

5.在画板上使用画笔画画:

模版代码:    

//1.创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
//2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());  
//3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);  
//5.在画板上使用画笔画画:    
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
5.计算机图形处理的原理
 计算机表示图形的时候时候是使用像素点来表示的,每个像素点都有一个颜色,每个颜色都是使用6位16进制的数值来表示的,一个像素点使用24个bit表示,也就是说使用24个0101字符串来表示。    
计算机在处理图形的时候修改的是图形文件中的0101的字符串。
6.计算机图形处理的API(重点)    
图片的平移、旋转、缩放、镜面、倒影的效果。
代码:
    public void trans(View view){  
//1.创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
//2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth()+100, srcBitmap.getHeight()+100, srcBitmap.getConfig());  
//3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);  
//5.在画板上使用画笔画画:        
Matrix matrix = new Matrix();    
matrix.setTranslate(100, 100);    
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    
canvas.drawBitmap(srcBitmap, matrix, paint);        
iv_copy.setImageBitmap(copyBitmap);   
}     
public void rotate(View view){  
//1.创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
//2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());  
//3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);  
//5.在画板上使用画笔画画:        
Matrix matrix = new Matrix();    
matrix.setRotate(90, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);    
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    canvas.drawBitmap(srcBitmap, matrix, paint);        
iv_copy.setImageBitmap(copyBitmap);   
}      
public void scale(View view){  
//  1、创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
//2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());  
//3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);  
//5.在画板上使用画笔画画:        
Matrix matrix = new Matrix();    
matrix.setScale(0.5f, 0.5f, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);    
 
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    
canvas.drawBitmap(srcBitmap, matrix, paint);        
iv_copy.setImageBitmap(copyBitmap);   
}     
public void jm(View view){  
//  1.创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
// 2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
 //3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);
//5.在画板上使用画笔画画:        
Matrix matrix = new Matrix();   
//设置镜面效果(把x坐标改成负值)    
matrix.setScale(-1.0f, 1.0f);    
//会使平移的效果立即显示出来    
matrix.postTranslate(srcBitmap.getWidth(), 0);    
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    canvas.drawBitmap(srcBitmap, matrix, paint);        
iv_copy.setImageBitmap(copyBitmap);   
}      
public void dy(View view){  
 
//  1.创建一个原图:    
//从资源文件目录中加载一个图片    
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);  
//2.参考原图创建一个空白纸张:    
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());  
//3.参考空白纸张创建一个画板:    
Canvas canvas = new Canvas(copyBitmap);  
//4.创建一支画笔:      
Paint paint = new Paint();    
//给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);  
//5.在画板上使用画笔画画:        
Matrix matrix = new Matrix();    
//设置镜面效果(把x坐标改成负值)    
matrix.setScale(1.0f, -1.0f);    
//会使平移的效果立即显示出来    
matrix.postTranslate(0, srcBitmap.getHeight());    
//srcBitmap 按照原图去画画    
//matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
//paint 画图使用的画笔    
canvas.drawBitmap(srcBitmap, matrix, paint);        
iv_copy.setImageBitmap(copyBitmap);   
}

7.撕衣服

原理(步骤):

 1.是布局文件中使用相对布局,显示两个重叠的imageview;  

2.给上面的imageview添加一个触摸监听器,监听移动的过程;  

3.把手所到之处的像素点的颜色改成透明色。

代码:

package com.qaa.syf;
 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 copyBitmap;   
private Bitmap srcBitmap;   
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);    
// 一、显示原图的副本      
srcBitmap = BitmapFactory.decodeResource(getResources(),      R.drawable.pre7);    
copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),      srcBitmap.getHeight(), srcBitmap.getConfig());    
canvas = new Canvas(copyBitmap);    
paint = new Paint();    
// 给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画    
paint.setColor(Color.BLACK);    // 5、在画板上使用画笔画画:    
// srcBitmap 按照原图去画画    
// matrix 修改图形的矩阵对象,它封装了各种修改图形的方法    
// paint 画图使用的画笔    
canvas.drawBitmap(srcBitmap, new Matrix(), paint);      
iv.setImageBitmap(copyBitmap);     
 // 二、给ImageView控件添加一个触摸的监听器,监听手触摸到的位置(像素点),把手所到之处的像素点改成透明色    
iv.setOnTouchListener(new OnTouchListener() {       
// 当手触摸到ImageView上时会调用这个方法    
 // v 当前视图对象(ImageView)    
 // event时间对象,包含了与事件相关的所有信息     
// 返回值,true表示当前事件结束、false表示当前事件正在进行     
@Override     
public boolean onTouch(View v, MotionEvent event) {      
// 获得触摸的事件类型      
int action = event.getAction();      
switch (action) {      
case MotionEvent.ACTION_DOWN:
// 按下的事件类型         
break;        
case MotionEvent.ACTION_MOVE:
// 移动的事件类型         
// 得到当前坐标点       
int startX = (int) event.getX();       
int startY = (int) event.getY();      
 // 把副本上的相应的坐标点都设置成透明色       
for (int i = -10; i < 10; i++) {        
for (int j = -10; j < 10; j++) {        
 if(Math.sqrt(i*i+j*j)<=10){         
copyBitmap.setPixel(startX + i, startY + j,           
Color.TRANSPARENT);         
}        
}       
}        
 // 把修改后的副本显示在ImageView上      
 iv.setImageBitmap(copyBitmap);         
// 获得移动后新的坐标点       
startX = (int) event.getX();       
startY = (int) event.getY();       
break;        
case MotionEvent.ACTION_UP:
// 离开的事件类型         
break;      
}      
// true表示当前事件结束、false表示当前事件正在进行     
 return true;     
}    
});     
}    
}

8.微信画画板

代码:

package com.qaa.painter;
 import java.io.File;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;    
import android.app.Activity;  
import android.graphics.Bitmap;  
import android.graphics.Bitmap.CompressFormat;  
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.os.Environment;  
import android.view.MotionEvent;  
import android.view.View;  
import android.view.View.OnTouchListener;  
import android.widget.ImageView;  
import android.widget.Toast;
 public class MainActivity extends Activity {
 private ImageView iv;  
private Bitmap copyBitmap;  
private Bitmap srcBitmap;  
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);      
srcBitmap = BitmapFactory.decodeResource(getResources(),     R.drawable.bg);   
copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),     srcBitmap.getHeight(), srcBitmap.getConfig());   
canvas = new Canvas(copyBitmap);   paint = new Paint();   
// 给画笔设置默认的颜色,在画画的过程中,会使用与原图相对应的颜色来画画   
paint.setColor(Color.BLACK);   // 5、在画板上使用画笔画画:   
// srcBitmap 按照原图去画画   
// matrix 修改图形的矩阵对象,它封装了各种修改图形的方法   
// paint 画图使用的画笔   
canvas.drawBitmap(srcBitmap, new Matrix(), paint);   
iv.setImageBitmap(copyBitmap);      
iv.setOnTouchListener(new OnTouchListener() {        
private int startX;    
private int startY;
   @Override    
public boolean onTouch(View v, MotionEvent event) {          
int action = event.getAction();          
switch (action) {     
case MotionEvent.ACTION_DOWN://按下的事件类型            
//得到开始位置的坐标点      
startX = (int) event.getX();      
startY = (int) event.getY();      
break;
case MotionEvent.ACTION_MOVE:
//按下的事件类型:      
//得到结束位置的坐标点      
int endX = (int) event.getX();      
int endY = (int) event.getY();      
//从开始坐标点画到结束坐标点      
canvas.drawLine(startX, startY, endX, endY, paint);            
//显示处理后的图片      
iv.setImageBitmap(copyBitmap);            
//获得新的开始位置的坐标点      
startX = (int) event.getX();      
startY = (int) event.getY();      
break;     }     
return true;    
}   
});        
}
     
public void red(View view){   
paint.setColor(Color.RED);  
}    
public void green(View view){   
paint.setColor(Color.GREEN);  
}    
public void blue(View view){   
paint.setColor(Color.BLUE);  
}    
public void brush(View view){   
//改变画笔轨迹的宽度   
paint.setStrokeWidth(10);  
}    
public void save(View view){      
try {    
File file = new File(Environment.getExternalStorageDirectory()+"/123.jpg");    
FileOutputStream fos = new FileOutputStream(file);    
//压缩保存一张图片    
//CompressFormat.JPEG 保存图片的格式    
//100 压缩的质量值 0:最小压缩,100:无损压缩    
//fos 保存文件使用的输出流    
copyBitmap.compress(CompressFormat.JPEG, 100, fos);    
fos.close();    
Toast.makeText(this, "保存成功", 0).show();   
} catch (Exception e) {   
 e.printStackTrace();   
}  
}  
}

9.视频播放器videoview(重点)

代码:    

//初始化视频播放器   
vv = (VideoView) findViewById(R.id.vv);   
//设置播放的资源文件的路径   vv.setVideoPath("http://192.168.1.88:8080/12.mp4");   
//开始播放   
vv.start();
10.音乐播放器API  
代码:
 package com.qaa.mediaplayer;
 import android.app.Activity;  
import android.media.AudioManager;  
import android.media.MediaPlayer;  
import android.media.MediaPlayer.OnPreparedListener;  
import android.os.Bundle;    
public class MainActivity extends Activity {     
private MediaPlayer mediaPlayer;     
@Override   
protected void onCreate(Bundle savedInstanceState) {    
super.onCreate(savedInstanceState);    
setContentView(R.layout.activity_main);    
try {     
mediaPlayer = new MediaPlayer();     
// 设置音频流类型     
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);     
// 设置要播放的资源文件路径     
mediaPlayer.setDataSource("http://192.168.1.88:8080/12.mp3");     
// 准备数据资源     
// mediaPlayer.prepare();//使用同步的方式准备数据资源 ,适用于加载本地资源     
// 使用异步的方式准备数据资源(使用一个单独的线程加载网络上一个数据资源),适用于加载网络上的资源     
mediaPlayer.prepareAsync();     
//添加一个准备数据完成的监听器     
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {            
/**      
* 数据准备完成后调用这个方法      
*/      
@Override      
public void onPrepared(MediaPlayer mp) {       
//开始播放       
mediaPlayer.start();      
}     
});         
} catch (Exception e) {     
e.printStackTrace();    
}   
}  
}
11.影音播放器的常用API
代码:  
package com.qaa.mediaplayer;
 import android.app.Activity;  
import android.media.AudioManager;  
import android.media.MediaPlayer;  
import android.media.MediaPlayer.OnPreparedListener;  
import android.os.Bundle;  
import android.view.View;    
public class MainActivity extends Activity {
 private MediaPlayer mediaPlayer;  
private int currentPositon = 0;
 @Override  
protected void onCreate(Bundle savedInstanceState) {   
super.onCreate(savedInstanceState);   
setContentView(R.layout.activity_main);
 }
 public void play(View view) {   
try {    
mediaPlayer = new MediaPlayer();    
// 设置音频流类型    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);    
// 设置要播放的资源文件路径    
mediaPlayer.setDataSource("http://192.168.20.88:8080/xpg.mp3");    
// 准备数据资源    // mediaPlayer.prepare();
//使用同步的方式准备数据资源 ,适用于家在本地资源    
// 使用异步的方式准备数据资源(使用一个单独的线程加载网络上一个数据资源),适用于加载网络上的资源    
mediaPlayer.prepareAsync();    
// 添加一个准备数据完成的监听器    
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    /**     
* 数据准备完成后调用这个方法     
*/     
@Override     
public void onPrepared(MediaPlayer mp) {      
// 开始播放      
mediaPlayer.start();
    }    
});
  } catch (Exception e) {    
e.printStackTrace();   
}  
}
 public void pause(View view) {   
if (mediaPlayer != null && mediaPlayer.isPlaying()) {    
mediaPlayer.pause();    
currentPositon = mediaPlayer.getCurrentPosition();   
}
 }
 public void resume(View view) {   
if (mediaPlayer != null) {    
mediaPlayer.seekTo(currentPositon);    
mediaPlayer.start();   
}
 }    
public void restart(View view) {   
if (mediaPlayer != null) {    
mediaPlayer.seekTo(0);    
mediaPlayer.start();   }
else{    
play(view);   
}
 }    
public void stop(View view) {   
if (mediaPlayer != null) {    
//停止播放    
mediaPlayer.stop();    
//释放mediaPlayer    
mediaPlayer.release();        
mediaPlayer= null;   
}
 }
 }

12.影音播放器的生命周期函数

 状态:   

空闲 new Mediaplayer(),reset();   

初始化:setDataSource();        

准备:prepare();   

开始:start();        

继续播放:seekTo();   

暂停:pause();        

完成:播放完毕;

13.照相机拍照(重点)

调用手机自带的拍照功能:

// 创建一个拍照的意图对象   
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  //告诉照相机的应用把照片存储哪个位置   
intent.putExtra(     MediaStore.EXTRA_OUTPUT,     Uri.fromFile(new File(Environment.getExternalStorageDirectory()       + "/a.jpg")));
  //调用手机自带的照相功能   startActivityForResult(intent, 0);  }  
14.录像机应用
调用手机自带的录像功能:
 // 创建一个录像的意图对象   
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
  //告诉照相机的应用把照片存储哪个位置   
intent.putExtra(     MediaStore.EXTRA_OUTPUT,     Uri.fromFile(new File(Environment.getExternalStorageDirectory()       + "/a.3gp")));
  //调用手机自带的录像功能   
startActivityForResult(intent, 0);