Android 多媒体编程笔记
2016-08-21 17:14
489 查看
加载大图片
图片在计算机中的大小=图片的总像素 * 每个像素占用的大小。Android保存图片像素信息,是用ARGB保存,A表示alpha透明度。
下面是几种位图的说明:
单色位图:只能表示2种颜色
使用两个数字:0和1
使用一个长度为1的二进制数字就可以表示了
每个像素占用1/8个字节
16色位图:能表示16种颜色
需要16个数字:0-15,0000 - 1111
使用一个长度为4的二进制数组就可以表示了
每个像素占用1/2个字节
256色位图:能表示256种颜色
需要256个数字:0 - 255,0000 0000 - 1111 1111
使用一个长度为8的二进制数字
每个像素占用1个字节
24位位图:
每个像素占用24位,也就是3个字节,所在叫24位位图
R:0-255,需要一个长度为8的二进制数字,占用1个字节
G:0-255,需要一个长度为8的二进制数字,占用1个字节
B:0-255,需要一个长度为8的二进制数字,占用1个字节
所以一张3200*4800的24位位图,在加载到Android中时占用的内存大小为3200*4800*(3+1)=61440个字节,60000k=58M,直接加载大图片会导致out of memory,所以我们需要加载缩小后的图片。
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private int calculateScaleSize(int originalWidth, int originalHeight, int destWidth, int destHeight) { // 这里采用向上取整,比如如果图片是屏幕的1.5倍大, // 如果取1的话还是可能会崩溃,所以此时应该向上取整为2 int scaleWidth = (int) Math.ceil(originalWidth * 1.0f / destWidth); int scaleHeight = (int) Math.ceil(originalHeight * 1.0f / destHeight); System.out.println(Math.max(scaleHeight, scaleWidth)+""); return Math.max(scaleHeight, scaleWidth); } public void click(View v) { // 获取图片的宽高,但是不解析图片 Options opt = new Options(); opt.inJustDecodeBounds = true; // BitmapFactory.decodeFile("sdcard/dog.jpg", opt); BitmapFactory.decodeResource(getResources(), R.drawable.dog, opt); int imageWidth = opt.outWidth; int imageHeight = opt.outHeight; // 获取屏幕的宽高 Display dp = getWindowManager().getDefaultDisplay(); int screenWidth = dp.getWidth(); int screenHeight = dp.getHeight(); // 缩放图片 opt.inSampleSize = calculateScaleSize(imageWidth, imageHeight, screenWidth, screenHeight); opt.inJustDecodeBounds = false; // Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opt); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.dog, opt); // 使用缩放后的图片显示在屏幕上 ImageView iv = (ImageView) findViewById(R.id.iv); iv.setImageBitmap(bm); } }
制作图像的副本
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 这个对象是只读的 Bitmap bmSrc = BitmapFactory.decodeFile("sdcard/photo3.jpg"); //创建图片的副本 //1.在内存中创建一个与原图大小一模一样的的bitmap对象 Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig()); //2.创建画笔对象 Paint paint = new Paint(); //3.创建画板对象,把白纸铺在画板上 Canvas canvas = new Canvas(bmCopy); //4.开始作画 canvas.drawBitmap(bmSrc, new Matrix(), paint); ImageView iv_src = (ImageView) findViewById(R.id.iv_src); ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy); iv_src.setImageBitmap(bmSrc); iv_copy.setImageBitmap(bmCopy); }
MediaPlayer播放音频
下面是官方MediaPlayer的状态图public class MusicService extends Service { MediaPlayer player; private Timer timer; @Override public IBinder onBind(Intent intent) { return new MusicController(); } class MusicController extends Binder implements MusicInterface { @Override public void play() { MusicService.this.play(); } @Override public void pause() { MusicService.this.pause(); } @Override public void continuePlay() { MusicService.this.continuePlay(); } @Override public void seekTo(int progress) { MusicService.this.seekTo(progress); } } @Override public void onCreate() { super.onCreate(); player = new MediaPlayer(); } @Override public void onDestroy() { super.onDestroy(); player.stop(); player.release(); player = null; if (timer != null) { timer.cancel(); timer = null; } } public void play() { player.reset(); try { player.setDataSource("sdcard/zxmzf.mp3"); // player.setDataSource("http://192.168.13.119:8080/bzj.mp3"); // player.prepare(); player.prepareAsync(); // player.start(); player.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { player.start(); addTimer(); } }); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void continuePlay() { player.start(); } public void pause() { player.pause(); } public void seekTo(int progress) { player.seekTo(progress); } public void addTimer() { if (timer == null) { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { int duration = player.getDuration(); int currentPosition = player.getCurrentPosition(); Message msg = MainActivity.handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putInt("duration", duration); bundle.putInt("currentPosition", currentPosition); msg.setData(bundle); MainActivity.handler.sendMessage(msg); } }, 5, 500); } } }
MediaPlayer+SurfaceView播放视频
SurfaceView提供了双缓冲技术,是一个重量级的控件,会占用很多的内存,所以SurfaceView只要不可见,就不会创建,可见时,才会创建。从可见变成不可见时会销毁。public class MainActivity extends Activity { private MediaPlayer player; static int currentPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SurfaceView sv = (SurfaceView) findViewById(R.id.sv); final SurfaceHolder sh = sv.getHolder(); sh.addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { if (player != null) { currentPosition = player.getCurrentPosition(); player.stop(); player.release(); player = null; } } @Override public void surfaceCreated(SurfaceHolder holder) { if (player == null) { player = new MediaPlayer(); player.reset(); try { player.setDataSource("sdcard/2.3gp"); player.setDisplay(sh); player.prepare(); player.start(); player.seekTo(currentPosition); } catch (Exception e) { e.printStackTrace(); } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); } }
使用vitamio播放视频
系统的MediaPlayer支持的音视频格式很有限,所以如果我们想要制作一个支持很多种格式的音视频播放器,一般会用FFMPEG来实现。FFMPEG是一个开源的音视频编解码库,用c语言编写,已经有人封装了Android的API的库vitamio给我们使用。
vitamio是以一个工程模块的方式提供给我们使用。
需要先导入eclipse,然后在我们自己的工程中链接这个库。
下面就是使用vitamio的一个例子
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 检查库是否存在 if (!LibsChecker.checkVitamioLibs(this)) {return;} VideoView vv = (VideoView) findViewById(R.id.vv); vv.setVideoPath("sdcard/4.rmvb"); vv.start(); vv.setMediaController(new MediaController(this)); } }
工程源码地址
点击查看源码相关文章推荐
- Android基础笔记(十七)- 多媒体编程
- Delphi初浅入门笔记之九:多媒体编程二(媒体播放器控件篇)
- Delphi初浅入门笔记之十一:多媒体编程四(画笔篇)
- Android: NDK编程入门笔记
- android多媒体学习笔记二
- android多媒体学习笔记一
- 数字图像处理编成入门笔记——第10章 图象处理编程工具及简单的多媒体编程
- android多媒体部分学习笔记四___ Matrix
- android 耳机系统笔记2 --多媒体设备各种状态
- Android: NDK编程入门笔记
- android多媒体学习笔记三___图像合成
- Delphi初浅入门笔记之十二:多媒体编程五(绘制文字篇)
- android笔记 编程心得
- ANDROID: NDK编程入门笔记
- Android: NDK编程入门笔记
- Delphi初浅入门笔记之十:多媒体编程三(打开图片篇)
- Android: NDK编程入门笔记
- android 学习笔记(四) 4.1 java编程基础
- Android: NDK编程入门笔记
- android多媒体学习笔记三___图像合成