日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android多媒体编程

發(fā)布時間:2025/4/16 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android多媒体编程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多媒體概念

  • 文字、圖片、音頻、視頻

計算機圖片大小的計算

圖片大小 = 圖片的總像素 * 每個像素占用的大小

  • 單色圖:每個像素占用1/8個字節(jié)
  • 16色圖:每個像素占用1/2個字節(jié)
  • 256色圖:每個像素占用1個字節(jié)
  • 24位圖:每個像素占用3個字節(jié)

加載大圖片到內(nèi)存

Android系統(tǒng)以ARGB表示每個像素,所以每個像素占用4個字節(jié),很容易內(nèi)存溢出

對圖片進行縮放

  • 獲取屏幕寬高
Display dp = getWindowManager().getDefaultDisplay(); int screenWidth = dp.getWidth(); int screenHeight = dp.getHeight();
  • 獲取圖片寬高
Options opts = new Options(); //請求圖片屬性但不申請內(nèi)存 opts.inJustDecodeBounds = true; BitmapFactory.decodeFile("sdcard/dog.jpg", opts); int imageWidth = opts.outWidth; int imageHeight = opts.outHeight;
  • 圖片的寬高除以屏幕寬高,算出寬和高的縮放比例,取較大值作為圖片的縮放比例
int scale = 1; int scaleX = imageWidth / screenWidth; int scaleY = imageHeight / screenHeight; if(scaleX >= scaleY && scaleX > 1){scale = scaleX; } else if(scaleY > scaleX && scaleY > 1){scale = scaleY; }
  • 按縮放比例加載圖片
//設(shè)置縮放比例opts.inSampleSize = scale;//為圖片申請內(nèi)存opts.inJustDecodeBounds = false;Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opts);iv.setImageBitmap(bm);

在內(nèi)存中創(chuàng)建圖片的副本

直接加載的bitmap對象是只讀的,無法修改,要修改圖片只能在內(nèi)存中創(chuàng)建出一個一模一樣的bitmap副本,然后修改副本

//加載原圖Bitmap srcBm = BitmapFactory.decodeFile("sdcard/photo3.jpg");iv_src.setImageBitmap(srcBm);//創(chuàng)建與原圖大小一致的空白bitmapBitmap copyBm = Bitmap.createBitmap(srcBm.getWidth(), srcBm.getHeight(), srcBm.getConfig());//定義畫筆Paint paint = new Paint();//把紙鋪在畫版上Canvas canvas = new Canvas(copyBm);//把srcBm的內(nèi)容繪制在copyBm上canvas.drawBitmap(srcBm, new Matrix(), paint);iv_copy.setImageBitmap(copyBm);

對圖片進行特效處理

  • 首先定義一個矩陣對象
    Matrix mt = new Matrix();
  • 縮放效果
//x軸縮放1倍,y軸縮放0.5倍mt.setScale(1, 0.5f);
  • 旋轉(zhuǎn)效果
//以copyBm.getWidth() / 2, copyBm.getHeight() / 2點為軸點,順時旋轉(zhuǎn)30度 mt.setRotate(30, copyBm.getWidth() / 2, copyBm.getHeight() / 2);
  • 平移
//x軸坐標(biāo)+10,y軸坐標(biāo)+20 mt.setTranslate(10, 20);
  • 鏡面
//把X坐標(biāo)都變成負數(shù) mt.setScale(-1, 1); //圖片整體向右移 mt.postTranslate(copyBm.getWidth(), 0);
  • 倒影
//把Y坐標(biāo)都變成負數(shù) mt.setScale(1, -1); //圖片整體向下移 mt.postTranslate(0, copyBm.getHeight());

畫畫板

在Android 中可以給View 控件設(shè)置觸摸事件監(jiān)聽,這些觸摸事件包括用戶點擊下去
(ACTION_DOWN),移動(ACTION_MOVE)和抬起(ACTION_UP)。隨手涂鴉就是給ImageView(所有的控件都是View 的子類,都具備觸摸監(jiān)聽功能)設(shè)置觸摸監(jiān)聽事件,然后在ImageView 控件上進行繪制線條操作。

當(dāng)用戶ACTION_DOWN 的時候獲取當(dāng)前的x 和y 坐標(biāo)作為要繪制線條的起始坐標(biāo),當(dāng)
ACTION_MOVE(該事件只要用戶在滑動就不斷的被調(diào)用)的時候不斷的獲取新的x 和y 坐標(biāo),將新的坐標(biāo)作為要繪制線條的結(jié)束坐標(biāo)就可以繪制一條直線,然后將結(jié)束坐標(biāo)再作為新線條的起始坐標(biāo),依次類推,就能繪制出無限多個小直線,這些直線最終看起來就像是曲線的效果了。

最后可以將繪制好的圖片保存到本地文件中。

記錄用戶觸摸事件的XY坐標(biāo),繪制直線。給ImageView設(shè)置觸摸偵聽,得到用戶的觸摸事件,并獲知用戶觸摸ImageView的坐標(biāo)

iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {//觸摸屏幕case MotionEvent.ACTION_DOWN://得到觸摸屏幕時手指的坐標(biāo)startX = (int) event.getX();startY = (int) event.getY();break;//在屏幕上滑動case MotionEvent.ACTION_MOVE://用戶滑動手指,坐標(biāo)不斷的改變,獲取最新坐標(biāo)int newX = (int) event.getX();int newY = (int) event.getY();//用上次onTouch方法得到的坐標(biāo)和本次得到的坐標(biāo)繪制直線canvas.drawLine(startX, startY, newX, newY, paint);iv.setImageBitmap(copyBm);startX = newX;startY = newY;break;}return true;} });
  • 刷子效果,加粗畫筆
paint.setStrokeWidth(8);
  • 調(diào)色板,改變畫筆顏色
paint.setColor(Color.GREEN);
  • 保存圖片至SD卡
FileOutputStream fos = null; try {fos = new FileOutputStream(new File("sdcard/dazuo.png")); } catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace(); } //保存圖片 copyBm.compress(CompressFormat.PNG, 100, fos);
  • 系統(tǒng)每次收到SD卡就緒廣播時,都會去遍歷sd卡的所有文件和文件夾,把遍歷到的所有多媒體文件都在MediaStore數(shù)據(jù)庫保存一個索引,這個索引包含多媒體文件的文件名、路徑、大小
  • 圖庫每次打開時,并不會去遍歷sd卡獲取圖片,而是通過內(nèi)容提供者從MediaStore數(shù)據(jù)庫中獲取圖片的信息,然后讀取該圖片
  • 系統(tǒng)開機或者點擊加載sd卡按鈕時,系統(tǒng)會發(fā)送sd卡就緒廣播,我們也可以手動發(fā)送就緒廣播
Intent intent = new Intent(); intent.setAction(Intent.ACTION_MEDIA_MOUNTED); intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); sendBroadcast(intent);

案例4:畫畫板

public class MainActivity extends Activity {private ImageView iv;int startX;int startY;private Canvas canvas;private Paint paint;private Bitmap bmCopy;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//加載畫畫板的背景圖Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.bg);bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());paint = new Paint();canvas = new Canvas(bmCopy);//繪制canvas.drawBitmap(bmSrc, new Matrix(), paint);iv = (ImageView) findViewById(R.id.iv);iv.setImageBitmap(bmCopy);//設(shè)置觸摸偵聽iv.setOnTouchListener(new OnTouchListener() {//觸摸屏幕時,觸摸事件產(chǎn)生時,此方法調(diào)用@Overridepublic 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 x = (int) event.getX();int y = (int) event.getY();canvas.drawLine(startX, startY, x, y, paint);//每次繪制完畢之后,本次繪制的結(jié)束坐標(biāo)變成下一次繪制的初始坐標(biāo)startX = x;startY = y;iv.setImageBitmap(bmCopy);break;//用戶手指離開屏幕case MotionEvent.ACTION_UP:break;}//true:告訴系統(tǒng),這個觸摸事件由我來處理//false:告訴系統(tǒng),這個觸摸事件我不處理,這時系統(tǒng)會把觸摸事件傳遞給imageview的父節(jié)點return true;}});}public void red(View v){paint.setColor(Color.RED);}public void green(View v){paint.setColor(Color.GREEN);}public void brush(View v){paint.setStrokeWidth(7);}public void save(View v){File file = new File("sdcard/dazuo.png");FileOutputStream fos = null;try {fos = new FileOutputStream(file);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}bmCopy.compress(CompressFormat.PNG, 100, fos);//發(fā)送sd卡就緒廣播Intent intent = new Intent();intent.setAction(Intent.ACTION_MEDIA_MOUNTED);intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));sendBroadcast(intent);} }

撕衣服

把穿內(nèi)衣和穿外衣的照片重疊顯示,內(nèi)衣照在下面,用戶滑動屏幕時,觸摸的是外衣照,把手指經(jīng)過的像素都置為透明,內(nèi)衣照就顯示出來了

使用幀布局疊加2 個ImageView,每個ImageView 負責(zé)顯示一張圖片,一張圖片有衣服,一張圖片沒有衣服,沒有衣服的圖片放置在下面,有衣服的圖片放置在上面。給上面的ImageView 設(shè)置觸摸的事件,當(dāng)手指觸摸到圖片上時,將手指觸摸到的點周邊的圖片的像素點設(shè)置為透明的,這樣下面的圖片就一點一點顯示出來了,從而有一種“撕衣服”的感覺。

在編寫該案例的時候應(yīng)該注意的事項如下:

1、 觸摸事件onTouch 的返回值必須設(shè)置為true,否則觸摸的事件將不被處理
2、 使用BitmapFactory 的decodeResouces 方法得到的圖片是沒有透明度的,即圖片格式為RGB_565,所
以若想能夠修改透明度,需要使用Canvas 對象對圖片進行重繪,重新繪制的圖片格式采用ARGB。
3、 加載圖片時需要對其進行一下壓縮,防止圖片與控件大小不匹配,導(dǎo)致觸摸時點對不上,達不到觸
摸哪里就設(shè)置哪里的像素點透明的效果。

iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_MOVE:int newX = (int) event.getX();int newY = (int) event.getY();//把指定的像素變成透明copyBm.setPixel(newX, newY, Color.TRANSPARENT);iv.setImageBitmap(copyBm);break;}return true;} });

每次只設(shè)置一個像素點太慢,以觸摸的像素為圓心,半徑為5畫圓,圓內(nèi)的像素全部置為透明

for (int i = -5; i < 6; i++) {for (int j = -5; j < 6; j++) {if(Math.sqrt(i * i + j * j) <= 5)copyBm.setPixel(newX + i, newY + j, Color.TRANSPARENT);} }

案例5:撕衣服

public class MainActivity extends Activity {private Bitmap bmCopy;private ImageView iv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.awaiyi);bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());Paint paint = new Paint();Canvas canvas = new Canvas(bmCopy);canvas.drawBitmap(bmSrc, new Matrix(), paint);iv = (ImageView) findViewById(R.id.iv);iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_MOVE:int x = (int) event.getX();int y = (int) event.getY();for(int i = -5; i <= 5; i++){for(int j = -5; j <= 5; j++){//把用戶劃過的坐標(biāo)置為透明色//改變指定的像素顏色if(Math.sqrt(i*i + j*j) <= 5){if(x + i < bmCopy.getWidth() && y + j < bmCopy.getHeight() && x + i >= 0 && y + j >= 0){bmCopy.setPixel(x + i, y + j, Color.TRANSPARENT);iv.setImageBitmap(bmCopy);}}}}break;}return true;}});} }

音樂播放器

播放服務(wù)

  • 播放音頻的代碼應(yīng)該運行在服務(wù)中,定義一個播放服務(wù)MusicService
  • 服務(wù)里定義play、stop、pause、continuePlay等方法
private void play() {// TODO Auto-generated method stubplayer.reset();try {player.setDataSource("sdcard/bzj.mp3");player.prepare();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} player.start();} private void pause() {player.pause(); } private void stop() {player.stop(); } private void continuePlay() {player.start(); }
  • 把這幾個方法抽取成一個接口MusicInterface
  • 定義一個中間人類,繼承Binder,實現(xiàn)MusicInterface
  • 先start啟動MusicService,再bind
Intent intent = new Intent(this, MusicService.class); startService(intent); bindService(intent, conn, BIND_AUTO_CREATE);

根據(jù)播放進度設(shè)置進度條

  • 獲取當(dāng)前的播放時間和當(dāng)前音頻的最長時間
int currentPosition = player.getCurrentPosition(); int duration = player.getDuration();
  • 播放進度需要不停的獲取,不停的刷新進度條,使用計時器每500毫秒獲取一次播放進度
  • 發(fā)消息至Handler,把播放進度放進Message對象中,在Handler中更新SeekBar的進度
Timer timer = new Timer(); timer.schedule(new TimerTask() {@Overridepublic void run() {int currentPosition = player.getCurrentPosition();int duration = player.getDuration();Message msg = Message.obtain();//把播放進度存入Message中Bundle data = new Bundle();data.putInt("currentPosition", currentPosition);data.putInt("duration", duration);msg.setData(data);MainActivity.handler.sendMessage(msg);} }, 5, 500);
  • 在Activity中定義Handler
static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {//取出消息攜帶的數(shù)據(jù)Bundle data = msg.getData();int currentPosition = data.getInt("currentPosition");int duration = data.getInt("duration");//設(shè)置播放進度sb.setMax(duration);sb.setProgress(currentPosition);}; };

拖動進度條改變播放進度

//給sb設(shè)置一個拖動偵聽sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//停止拖動時調(diào)用@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubint progress = seekBar.getProgress();mi.seekTo(progress);}//開始拖動時調(diào)用 @Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}//拖動的時候不斷調(diào)用 @Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stub} });

視頻播放器

SurfaceView

  • 對畫面的實時更新要求較高
  • 雙緩沖技術(shù):內(nèi)存中有兩個畫布,A畫布顯示至屏幕,B畫布在內(nèi)存中繪制下一幀畫面,繪制完畢后B顯示至屏幕,A在內(nèi)存中繼續(xù)繪制下一幀畫面
  • 播放視頻也是用MediaPlayer,不過跟音頻不同,要設(shè)置顯示在哪個SurfaceView
SurfaceView sv = (SurfaceView) findViewById(R.id.sv);SurfaceHolder sh = sv.getHolder();MediaPlayer player = new MediaPlayer();player.reset();try {player.setDataSource("sdcard/2.3gp");player.setDisplay(sh);player.prepare();} catch (Exception e) {e.printStackTrace();}player.start();
  • SurfaceView是重量級組件,可見時才會創(chuàng)建
  • 給SurfaceHolder設(shè)置CallBack,類似于偵聽,可以知道SurfaceView的狀態(tài)
  • SurfaceView一旦不可見,就會被銷毀,一旦可見,就會被創(chuàng)建,銷毀時停止播放,再次創(chuàng)建時再開始播放
sh.addCallback(new Callback() {//SurfaceView銷毀時調(diào)用@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}//SurfaceView創(chuàng)建時調(diào)用@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stub}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub} });

攝像頭

  • 啟動系統(tǒng)提供的拍照程序
//隱式啟動系統(tǒng)提供的拍照ActivityIntent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//設(shè)置照片的保存路徑File file = new File(Environment.getExternalStorageDirectory(), "haha.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent, 0);
  • 啟動系統(tǒng)提供的攝像程序
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);File file = new File(Environment.getExternalStorageDirectory(), "haha.3gp"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //設(shè)置保存視頻文件的質(zhì)量intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);startActivityForResult(intent, 0);

多媒體編程

  • 文本、圖片、音頻、視頻

圖片

  • 圖片在計算機中的大小
  • 圖片的總大小 = 圖片的總像素 * 每個像素占用的大小
  • 單色位圖:只能表示2種顏色
    • 使用兩個數(shù)字:0和1
    • 使用一個長度為1的二進制數(shù)字就可以表示了
    • 每個像素占用1/8個字節(jié)
  • 16色位圖:能表示16種顏色
    • 需要16個數(shù)字:0-15,0000 - 1111
    • 使用一個長度為4的二進制數(shù)組就可以表示了
    • 每個像素占用1/2個字節(jié)
  • 256色位圖:能表示256種顏色
    • 需要256個數(shù)字:0 - 255,0000 0000 - 1111 1111
    • 使用一個長度為8的二進制數(shù)字
    • 每個像素占用1個字節(jié)
  • 24位位圖:
    • 每個像素占用24位,也就是3個字節(jié),所在叫24位位圖
    • R:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)
    • G:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)
    • B:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)

加載大圖片

  • 計算機把圖片所有像素信息全部解析出來,保存至內(nèi)存
  • Android保存圖片像素信息,是用ARGB保存
  • 手機屏幕320*480,總像素:153600
  • 圖片寬高2400*3200,總像素7680000
  • 2400 / 320 = 7
  • 3200 / 480 = 6

創(chuàng)建圖片副本

  • 在內(nèi)存中創(chuàng)建一個圖片的拷貝

保存圖片

  • SD每次準(zhǔn)備的時候,系統(tǒng)其實是遍歷sd卡所有文件,系統(tǒng)會把所有的多媒體文件,都在MediaStore數(shù)據(jù)庫中生成一個索引,數(shù)據(jù)庫中保存了文件的文件名、路徑、大小、長度和藝術(shù)家
  • 圖庫、音樂、視頻程序每次啟動時,其實不會去遍歷sd卡尋找多媒體文件,而是直接從MediaStore數(shù)據(jù)庫中讀取多媒體文件,通過庫中的索引找到對應(yīng)的多媒體文件后,把文件顯示在界面

SurfaceView

  • 雙緩沖技術(shù)
  • 重量級組件
  • 只要不可見,就不會創(chuàng)建,可見時,才會創(chuàng)建
  • 只要不可見,就會銷毀

FFMPEG

  • 開源免費的音視頻編解碼器

Vitamio

  • 封裝了FFMPEG的視頻播放框架
  • 對外提供的api全部都是javaApi

案例1:加載大圖片

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View v){//解析圖片時需要使用到的參數(shù)都封裝在這個對象里了Options opt = new Options();//不為像素申請內(nèi)存,只獲取圖片寬高opt.inJustDecodeBounds = true;BitmapFactory.decodeFile("sdcard/dog.jpg", opt);//拿到圖片寬高int imageWidth = opt.outWidth;int imageHeight = opt.outHeight;Display dp = getWindowManager().getDefaultDisplay();//拿到屏幕寬高int screenWidth = dp.getWidth();int screenHeight = dp.getHeight();//計算縮放比例int scale = 1;int scaleWidth = imageWidth / screenWidth;int scaleHeight = imageHeight / screenHeight;if(scaleWidth >= scaleHeight && scaleWidth >= 1){scale = scaleWidth;}else if(scaleWidth < scaleHeight && scaleHeight >= 1){scale = scaleHeight;}//設(shè)置縮放比例opt.inSampleSize = scale;opt.inJustDecodeBounds = false;Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opt);ImageView iv = (ImageView) findViewById(R.id.iv);iv.setImageBitmap(bm);}}

案例2:創(chuàng)建圖片的副本

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//這個對象是只讀的Bitmap bmSrc = BitmapFactory.decodeFile("sdcard/photo3.jpg");//創(chuàng)建圖片副本//1.在內(nèi)存中創(chuàng)建一個與原圖一模一樣大小的bitmap對象,創(chuàng)建與原圖大小一致的白紙Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());//2.創(chuàng)建畫筆對象Paint paint = new Paint();//3.創(chuàng)建畫板對象,把白紙鋪在畫板上Canvas canvas = new Canvas(bmCopy);//4.開始作畫,把原圖的內(nèi)容繪制在白紙上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);} }

案例3:圖片的簡單特效

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//這個對象是只讀的Bitmap bmSrc = BitmapFactory.decodeFile("sdcard/photo3.jpg");//創(chuàng)建圖片副本//1.在內(nèi)存中創(chuàng)建一個與原圖一模一樣大小的bitmap對象,創(chuàng)建與原圖大小一致的白紙Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());//2.創(chuàng)建畫筆對象Paint paint = new Paint();//3.創(chuàng)建畫板對象,把白紙鋪在畫板上Canvas canvas = new Canvas(bmCopy);//4.開始作畫,把原圖的內(nèi)容繪制在白紙上Matrix mt = new Matrix();//平移 // mt.setTranslate(20, 40);//縮放//sx:水平方向的縮放比例//sy:豎直方向的縮放比例 // mt.setScale(0.5f, 0.5f); // mt.setScale(0.5f, 0.5f, bmCopy.getWidth() / 2, bmCopy.getHeight() / 2);//旋轉(zhuǎn) // mt.setRotate(45, bmCopy.getWidth() / 2, bmCopy.getHeight() / 2);//鏡面 // mt.setScale(-1, 1); // mt.postTranslate(bmCopy.getWidth(), 0);//倒影mt.setScale(1, -1);mt.postTranslate(0, bmCopy.getHeight());canvas.drawBitmap(bmSrc, mt, 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);} }

案例6:播放音樂

package com.itheima.musicplayer;public interface MusicInterface {void play();void pause();void continuePlay();void seekTo(int progress); } public class MusicService extends Service {MediaPlayer player;private Timer timer;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn new MusicController();}class MusicController extends Binder implements MusicInterface{@Overridepublic void play() {MusicService.this.play();}@Overridepublic void pause() {MusicService.this.pause();}@Overridepublic void continuePlay() {MusicService.this.continuePlay();}@Overridepublic void seekTo(int progress) {MusicService.this.seekTo(progress);}}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();player = new MediaPlayer();}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();//停止播放player.stop();//釋放占用的資源,此時player對象已經(jīng)廢掉了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() {//準(zhǔn)備完畢時,此方法調(diào)用@Overridepublic void onPrepared(MediaPlayer mp) {player.start();addTimer();}});} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }//繼續(xù)播放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() {@Overridepublic void run() {//獲取歌曲總時長int duration = player.getDuration();//獲取歌曲當(dāng)前播放進度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);}//開始計時任務(wù)后的5毫秒,第一次執(zhí)行run方法,以后每500毫秒執(zhí)行一次}, 5, 500);}} } public class MainActivity extends Activity {static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {Bundle bundle = msg.getData();int duration = bundle.getInt("duration");int currentPostition = bundle.getInt("currentPosition");//刷新進度條的進度sb.setMax(duration);sb.setProgress(currentPostition);}};MusicInterface mi;private MyserviceConn conn;private Intent intent;private static SeekBar sb;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sb = (SeekBar) findViewById(R.id.sb);sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//根據(jù)拖動的進度改變音樂播放進度int progress = seekBar.getProgress();//改變播放進度mi.seekTo(progress);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {}});intent = new Intent(this, MusicService.class);startService(intent);conn = new MyserviceConn();bindService(intent, conn, BIND_AUTO_CREATE);}class MyserviceConn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mi = (MusicInterface) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}}public void play(View v){mi.play();}public void continuePlay(View v){mi.continuePlay();}public void pause(View v){mi.pause();}public void exit(View v){unbindService(conn);stopService(intent);}}

案例7:播放視頻

public class MainActivity extends Activity {private MediaPlayer player;static int currentPosition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SurfaceView sv = (SurfaceView) findViewById(R.id.sv);//拿到surfaceview的控制器final SurfaceHolder sh = sv.getHolder();// Thread t = new Thread(){ // @Override // public void run() { // // TODO Auto-generated method stub // try { // sleep(200); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // runOnUiThread(new Runnable() { // @Override // public void run() { // MediaPlayer player = new MediaPlayer(); // player.reset(); // try { // player.setDataSource("sdcard/2.3gp"); // player.setDisplay(sh); // player.prepare(); // player.start(); // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // } // }); // // } // }; // t.start();sh.addCallback(new Callback() {//surfaceView銷毀時調(diào)用@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {//每次surfaceview銷毀時,同時停止播放視頻if(player != null){currentPosition = player.getCurrentPosition();player.stop();player.release();player = null;}}//surfaceView創(chuàng)建時調(diào)用@Overridepublic void surfaceCreated(SurfaceHolder holder) {//每次surfaceView創(chuàng)建時才去播放視頻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) {// TODO Auto-generated catch blocke.printStackTrace();} }}//surfaceView結(jié)構(gòu)改變時調(diào)用@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}});}}

案例8:VideoView

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//檢測是否支持vitamioif (!LibsChecker.checkVitamioLibs(this)) {return;}VideoView vv = (VideoView) findViewById(R.id.vv);vv.setVideoPath("sdcard/4.rmvb");vv.start();vv.setMediaController(new MediaController(this));} }

案例9:攝像頭

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void image(View v){//啟動系統(tǒng)提供的拍照activityIntent intent = new Intent();intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "haha.jpg")));startActivityForResult(intent, 10);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if(requestCode == 10){Toast.makeText(this, "拍照成功", 0).show();}else if(requestCode == 20){Toast.makeText(this, "攝像成功", 0).show();}}public void video(View v){//啟動系統(tǒng)提供的攝像activityIntent intent = new Intent();intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "haha.3gp")));intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);startActivityForResult(intent, 20);}}

案例10:vitamio_lib

總結(jié)

以上是生活随笔為你收集整理的Android多媒体编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。