安卓入门
九、多媒体
1、图片
a、缩放图片原理
public class MainActivity extends AppCompatActivity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = findViewById(R.id.iv);
}
public void btnHandle(View view) {
//获取屏幕的宽和高
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();
int height = wm.getDefaultDisplay().getHeight();
System.out.println("{width:" + width + ",height:" + height + "}");
//不解析位图,获取位图的宽和高
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile("/mnt/sdcard/mmq5.bmp", options);
int imgWidth = options.outWidth;
int imgHeight = options.outHeight;
System.out.println("{imgWidth:" + imgWidth + ",imgHeight:" + imgHeight + "}");
//计算缩放比
int scale = 1;
int scaleX = imgWidth / width;
int scaleY = imgHeight / height;
if (scaleX > scaleY) {
scale = scaleX;
} else {
scale = scaleY;
}
System.out.println("{scale:" + scale + "}");
//显示到控件上
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile("/mnt/sdcard/mmq5.bmp", options);
iv.setImageBitmap(bm);
}
}
b、原图副本的操作
public class MainActivity extends AppCompatActivity {
private ImageView iv;
private ImageView ivCopy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = findViewById(R.id.iv);
ivCopy = findViewById(R.id.iv_copy);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);
iv.setImageBitmap(bm);
//创建原图副本
Bitmap bmCopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());
//创建画笔
Paint paint = new Paint();
//创建画布
Canvas canvas = new Canvas(bmCopy);
//图形处理api
Matrix matrix = new Matrix();
//* 旋转
//matrix.setRotate(20, bm.getWidth() / 2, bm.getHeight() / 2);
//* 缩放
//matrix.setScale(0.5f, 0.5f);
//* 平移
//matrix.setTranslate(30, 0);
//* 镜面
//matrix.setScale(-1, 1);
//matrix.postTranslate(bm.getWidth(), 0);
//* 倒影
matrix.setScale(1, -1);
matrix.postTranslate(0, bm.getHeight());
//开始画
canvas.drawBitmap(bm, matrix, paint);
//设置图片像素点
for (int i = 0; i < 100; i++) {
bmCopy.setPixel(i, 30, Color.RED);
}
ivCopy.setImageBitmap(bmCopy);
}
}
c、画画板案例
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public class MainActivity extends AppCompatActivity {
private ImageView ivCopy;
private Paint paint;
private Bitmap bmCopy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivCopy = findViewById(R.id.iv_copy);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);
bmCopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());
paint = new Paint();
Canvas canvas = new Canvas(bmCopy);
Matrix matrix = new Matrix();
canvas.drawBitmap(bm, matrix, paint);
ivCopy.setImageBitmap(bmCopy);
ivCopy.setOnTouchListener(new View.OnTouchListener() {
private float startX = 0;
private float startY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float stopX = event.getX();
float stopY = event.getY();
canvas.drawLine(startX, startY, stopX, stopY, paint);
ivCopy.setImageBitmap(bmCopy);
startX = stopX;
startY = stopY;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
}
public void changeColor(View view) {
paint.setColor(Color.RED);
}
public void changeStrokeWidth(View view) {
paint.setStrokeWidth(15);
}
public void saveHandle(View view) {
try {
String path = Environment.getExternalStorageDirectory().getPath();
//获取手机开机时间
long uptimeMillis = SystemClock.uptimeMillis();
File file = new File(path, uptimeMillis + ".png");
FileOutputStream fos = new FileOutputStream(file);
//将图片写入到本地存储
bmCopy.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
//发送广播,使系统图库应用加载图片
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
}
}
2、音频
a、百度音乐盒案例
<service android:name=".MusicService" />
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="playMusic"
android:text="播放" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="suspendMusic"
android:text="暂停" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="replayMusic"
android:text="继续播放" />
<SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private IMusicService iMusicService;
private MyServiceConnection connection;
private static SeekBar sb;
//通过handler传送数据
public static Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
Bundle data = msg.getData();
int duration = data.getInt("duration");
int currentPosition = data.getInt("currentPosition");
sb.setMax(duration);
sb.setProgress(currentPosition);
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MusicService.class);
startService(intent);
connection = new MyServiceConnection();
bindService(intent, connection, BIND_ABOVE_CLIENT);
sb = findViewById(R.id.sb);
//绑定seekBar监听事件
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//seekBar改变时调用
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
//seekBar拖动时调用
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
//seekBar停止拖动时调用
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int position = seekBar.getProgress();
iMusicService.callSeekTo(position);
}
});
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
public void playMusic(View view) {
iMusicService.callPlayMusic();
}
public void suspendMusic(View view) {
iMusicService.callSuspendMusic();
}
public void replayMusic(View view) {
iMusicService.callReplayMusic();
}
//通过ServiceConnection获取Binder
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMusicService = (IMusicService) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
@Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
super.onCreate();
}
public void playMusic() {
try {
//音频重置
mediaPlayer.reset();
// 播放异步资源需要加<uses-permission android:name="android.permission.INTERNET" />权限
mediaPlayer.setDataSource("/mnt/sdcard/tik tok.mp3");
//异步音频准备
//mediaPlayer.prepareAsync();
//异步音频准备完毕监听事件
/*
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
*/
//音频准备
mediaPlayer.prepare();
//音频播放
mediaPlayer.start();
// 更新seekBar
updateSeekBar();
} catch (IOException e) {
e.printStackTrace();
}
}
private void updateSeekBar() {
//获取音频长度
int duration = mediaPlayer.getDuration();
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
int currentPosition = mediaPlayer.getCurrentPosition();
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putInt("duration", duration);
bundle.putInt("currentPosition", currentPosition);
msg.setData(bundle);
//handler调用sendMessage()时,handler会执行handleMessage(),通过Message传送数据
MainActivity.handler.sendMessage(msg);
}
};
//设置一个定时器,参数1:延迟时间,参数2:周期时间
timer.schedule(timerTask, 100, 1000);
//音频播放结束事件
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
timerTask.cancel();
timer.cancel();
}
});
}
public void suspendMusic() {
//音频暂停
mediaPlayer.pause();
}
public void replayMusic() {
mediaPlayer.start();
}
private void seekTo(int position) {
//跳转音频播放位置
mediaPlayer.seekTo(position);
}
private class MyBinder extends Binder implements IMusicService {
@Override
public void callPlayMusic() {
playMusic();
}
@Override
public void callSuspendMusic() {
suspendMusic();
}
@Override
public void callReplayMusic() {
replayMusic();
}
@Override
public void callSeekTo(int position) {
seekTo(position);
}
}
}
public interface IMusicService {
void callPlayMusic();
void callSuspendMusic();
void callReplayMusic();
void callSeekTo(int position);
}
3、视频
a、SurfaceView
<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sfv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private int currentPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//可在子线程直接更新UI
SurfaceView sfv = findViewById(R.id.sfv);
SurfaceHolder holder = sfv.getHolder();
//控件回调事件
holder.addCallback(new SurfaceHolder.Callback() {
//控件创建回调方法
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
mediaPlayer = new MediaPlayer();
try {
//设置数据源
mediaPlayer.setDataSource("https://www.runoob.com/try/demo_source/movie.mp4");
//媒体异步准备
mediaPlayer.prepareAsync();
//设置媒体的播放控件
mediaPlayer.setDisplay(holder);
//媒体准备监听事件
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
//媒体准备完毕事件
@Override
public void onPrepared(MediaPlayer mp) {
//开始播放
mediaPlayer.start();
//跳转播放位置
mediaPlayer.seekTo(currentPosition);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
//控件改变回调方法
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
//控件销毁回调方法
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
//获取播放位置
currentPosition = mediaPlayer.getCurrentPosition();
//播放停止
mediaPlayer.stop();
}
}
});
}
}
b、VideoView
<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<VideoView
android:id="@+id/vv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//是对MediaPlayer和SurfaceView的封装
VideoView vv = findViewById(R.id.vv);
vv.setVideoPath("https://www.runoob.com/try/demo_source/movie.mp4");
vv.start();
}
}
c、调用照相和摄像接口
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void photographHandle(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory().getPath(), "haha.png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, 1);
}
public void cameraHandle(View view) {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory().getPath(), "hehe.mp4");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
}