一路繁花似锦绣前程
失败的越多,成功才越有价值

导航

 

安卓入门

九、多媒体

1、图片
a、缩放图片原理
  • MainActivity
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、原图副本的操作
  • MainActivity
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" />
  • MainActivity
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" />
  • activity_main.xml
<?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>
  • MainActivity
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) {

        }
    }
}
  • MusicService
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);
        }
    }
}
  • IMusicService
public interface IMusicService {
    void callPlayMusic();

    void callSuspendMusic();

    void callReplayMusic();

    void callSeekTo(int position);
}
3、视频
a、SurfaceView
  • 清单文件
<uses-permission android:name="android.permission.INTERNET" />
  • AndroidManifest.xml
<?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>
  • MainActivity
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" />
  • AndroidManifest.xml
<?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>
  • MainActivity
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、调用照相和摄像接口
  • MainActivity
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);
    }
}
posted on 2021-12-17 14:48  一路繁花似锦绣前程  阅读(27)  评论(0编辑  收藏  举报