一、图片:
存放在内存中的图像数据会通过Bitmap对象来表示,实现了Parcelable接口,说明图像数据可以进行序列化和反序列化,便捷地在进程间传递。
不同格式的图像数据在内存中有着不同的存储方式,占用的内存大小不同。
在图片使用完毕后,手动释放图片占用的内存空间,保证内存可以更快的进行回收:
if(!bitmap.isRecycled()){
//对图片进行处理
...
//手动释放内存
bitmap.recycle();
bitmap = null;
}
1.图像的读取和输出
图像的读取用BitmapFactory类来处理,使用BitmapFactory可以从不同的数据源中读取图像数据:
比如从图像文件中读取(参数为文件的绝对路径):BitmapFactory.decodeFile(“sdcard/example.png”);
从资源文件中读取:BitmapFactory.decodeResource(R.drawable.example);
从流中读取:BitmapFactory.decodeStream(inputStream);
读取到内存的图片文件过大时,可能会导致内存溢出,所以读取大图片需要控制读入的图像大小,使用BitmapFactory.Options对象可以设置图像读取的参数,in开头的参数表示控制图像读取的输入参数,以out开头的参数用来预取该图片文件中图像的基本信息,比如长度、宽度、图片类型等。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile("sdcard/example.jpg",options);
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
Display display = getWindowManager().getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
int scale = 1;
int scaleWidth = imageWidth / screenWidth;
int scaleHeight = imageHeight / screenHeight;
if(scaleWidth > scaleHeight && scaleWidth > 1){
scale = scaleWidth;
}else if(scaleHeight > scaleWidth && scaleHeight > 1){
scale = scaleHeight;
}
options.inJustDecodeBounds = false;
options.inSampleSize = scale;
Bitmap bm = BitmapFactory.decodeFile("sdcard/example.jpg",options);
通过Bitmap.compress方法将内存中的图像压缩成png,gif,jpg等格式输出出来。既可以输出到本地文件中,也可以直接输出到网络流中
bitmap.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
2.图像的呈现
ImageView适用于简单的小图像呈现(比如图标、用户头像),在其他很多场景下,开发者需要自行控制图像的读取或交互。比如大图片不能使用ImageView.setImageURI函数设置文件路径,而需要对图片进行读取和压缩,再调用ImageVIew.setImageBitmap函数呈现图片文件。
对图片进行一些自定义的操作,需要拷贝图片副本,然后运用Paint的相关函数对图片进行操作:
//这个图片是只读的
Bitmap bm = BitmapFactory.decodeFile("sdcard/example.png");
//创建一个与原图大小相同的空白Bitmap对象
Bitmap bitmap = Bitmap.createBitmap(bm.getWidth(),bm.getHeight(),bm.getConfig());
//创建画笔对象
Paint paint = new Paint();
//利用空白的Bitmap对象创建画板
Canvas canvas = new Canvas(bitmap);
//将原图的内容绘制在空白的Bitmap对象上
canvas.drawBitmap(bm,new Matrix(),paint);
3.图片的管理
图片的三级缓存
二、音视频
音视频操作中最核心的编码解码、进度控制等功能实现,由开源项目OpenCORE提供,android.media包通过JNI方式封装了OpenCORE的实现
MediaPlayer
数据源可以是存放在资源文件中的音视频信息,也可以是存储在扩展存储器中的音视频文件,也可以是来自网络的音视频流(必须是流格式不能是数据块格式,否则必须先下载到本地扩展存储设备中再进行播放)
基本格式和常用API:
final MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource("sdcard/example.mp3");
// mediaPlayer.prepare();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer.reset();
mediaPlayer.pause();
mediaPlayer.stop();
mediaPlayer.release();
MediaRecoder
MediaRecorder recorder = new MediaRecorder();
//初始化需要录制的文件来源、格式、路径
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("sdcard/record.3gp");
//开始录制
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
e.printStackTrace();
}
三、相机
1.使用第三方摄像应用来完成拍照或视频录制
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//由于拍摄的图片较大,因此可以为拍照应用指定一个文件地址,存放照片
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//发出请求,并等待回调
startActivityForResult(intent, REQUEST_CODE);
拍摄完成后,回调该函数
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
image_uri = data.getData();
}
}
摄像
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(getFilesDir(), "video.3gp")));
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);
startActivityForResult(intent,20);