【读书笔记】《Android多媒体开发高级编程》(一)

第一章 Android图像概述

1. 调用系统摄像头, onActivityResult中获取的图片是经过压缩之后的。一般比较小。

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(i, REQUEST_CODE_CAMERA);
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_CAMERA){
            if (resultCode == RESULT_OK){
                if (data != null) { 
                    Bundle extras = data.getExtras();
                    Bitmap bmp = (Bitmap) extras.get("data");
                    mImageView.setImageBitmap(bmp);
                }
            }
        }
    }

2. 要获取更大的图像,可以使用BitmapFactory.Options进行缩放。

@NonNull
    private BitmapFactory.Options getBitmapOptions() {
        Display currentDisplay = getWindowManager().getDefaultDisplay();
        int dw = currentDisplay.getWidth(); //最大宽度
        int dh = currentDisplay.getHeight(); //最大高度

        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

        bmpFactoryOptions.inJustDecodeBounds = true; //只解析大小,不解析图片
        Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

        int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh); //高度比
        int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw); //宽度比

        if (heightRatio > 1 && widthRatio > 1){
            bmpFactoryOptions.inSampleSize = Math.max(widthRatio, heightRatio); //以压缩大的比例为最终缩放比例
//        bmpFactoryOptions.inSampleSize = 8; //产生一幅大小是原始大小1/8的图像
        }

        bmpFactoryOptions.inJustDecodeBounds = false; //解析图片
        return bmpFactoryOptions;
    }
private void setImageFromSD(){
        BitmapFactory.Options bmpFactoryOptions = getBitmapOptions();
        Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
        mImageView.setImageBitmap(bmp);
    }

3. 保存原图,方法一,把图片保存到sd卡

//方法一: 保存图片到sd卡
imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "mypic.jpg";
File imageFile = new File(imageFilePath);
imageFileUri = Uri.fromFile(imageFile);

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(i, REQUEST_CODE_CAMERA);

注意:此时onActivityResult里面data就会为null。所以不能直接从data显示图片,而是要从文件显示。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_CAMERA){
            if (resultCode == RESULT_OK){
                if (data != null) { //如果指定了MediaStore.EXTRA_OUTPUT, 则此处data为null
                    Bundle extras = data.getExtras();
                    Bitmap bmp = (Bitmap) extras.get("data");
                    mImageView.setImageBitmap(bmp);
                }else{
                    BitmapFactory.Options bmpFactoryOptions = getBitmapOptions();
                    Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
                    mImageView.setImageBitmap(bmp);
                }
            }
        }
    }

4. 保存原图,方法二,使用MediaStore进行图像存储及元数据关联。

//方法二: 使用MediaStore和content resolver
ContentValues contentValues = new ContentValues(3);
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "This is a test title");
contentValues.put(MediaStore.Images.Media.DESCRIPTION, "This is a test description");
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
//此处有一个坑。 每次进拍照页面的时候,就已经insert了一个了。但是我实际可以不拍照就返回,这样就会有一个空的数据。所以要在onActivityResult里面判断,cancel的时候,要删掉
imageFileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); //创建一个新的uri
imageFilePath = imageFileUri.getPath();
//如果需要更新一条已有的uri, 使用getContentResolver().update(imageFileUri, contentValues, null, null);

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(i, REQUEST_CODE_CAMERA);

由于每次点击拍照,都会insert一个记录,如果不拍照的话,就会有一条多余的数据了。所以在onActivityResult里面要判断,如果取消了,要删除那一条多余的数据。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_CAMERA){
            if (resultCode == RESULT_OK){
                if (data != null) { //如果指定了MediaStore.EXTRA_OUTPUT, 则此处data为null
                    Bundle extras = data.getExtras();
                    Bitmap bmp = (Bitmap) extras.get("data");
                    mImageView.setImageBitmap(bmp);
                }else{
                    //使用content resolver解析图片
                    BitmapFactory.Options bmpFactoryOptions = getBitmapOptions();
                    Bitmap bmp;
                    try {
                        bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);
                        mImageView.setImageBitmap(bmp);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }else{
                //取消了的话,uri的新纪录也要删掉
                getContentResolver().delete(imageFileUri, null, null);
            }
        }
    }
5. 使用 Cursor 查询图片,用 ExifInterface 获取或设置图片信息

//最近三天的照片
        mImageTitleTextView = (TextView)findViewById(R.id.imageTitleTextView);
        mExifDescTextView = (TextView)findViewById(R.id.imageExifDescTextView);

        String [] columns = {Media.DATA, Media._ID, Media.TITLE, Media.DISPLAY_NAME, Media.DATE_ADDED};
        long threeDaysAgo = System.currentTimeMillis()/1000 - 3 * 24 * 60 * 60; //单位用秒,因为Media.DATE_ADDED的单位是秒
        String [] whereValues = {String.valueOf(threeDaysAgo)};
        final Cursor cursor = managedQuery(Media.EXTERNAL_CONTENT_URI, columns, Media.DATE_ADDED + " > ?", whereValues, Media.DATE_ADDED +  " asc");
        if (cursor.moveToFirst()){
            setImageFromCursor(cursor);
        }

        mShowPrevButton = (Button)findViewById(R.id.showPicPrev);
        mShowPrevButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cursor.moveToPrevious()){
                    setImageFromCursor(cursor);
                }else{
                    showToast(R.string.already_the_first);
                }
            }
        });

        mShowNextButton = (Button)findViewById(R.id.showPicNext);
        mShowNextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cursor.moveToNext()) {
                    setImageFromCursor(cursor);
                } else {
                    showToast(R.string.already_the_last);
                }
            }
        });

private void setImageFromCursor(Cursor cursor){
        int fileColumn = cursor.getColumnIndexOrThrow(Media.DATA);
        int titleColumn = cursor.getColumnIndexOrThrow(Media.TITLE);
        int displayColumn = cursor.getColumnIndexOrThrow(Media.DISPLAY_NAME);
        String displayName = cursor.getString(titleColumn) + " - " + cursor.getString(displayColumn);
        mImageTitleTextView.setText(displayName);
        imageFilePath = cursor.getString(fileColumn);
        File imageFile = new File(imageFilePath);
        if (!imageFile.exists()){
            //这是之前insert了一条记录,但是没有拍照产生的脏数据,删掉
            int _idColumn = cursor.getColumnIndexOrThrow(Media._ID);
            int _id = cursor.getInt(_idColumn);
            getContentResolver().delete(Media.EXTERNAL_CONTENT_URI, Media._ID + " = ?", new String[]{String.valueOf(_id)});

            mExifDescTextView.setText("");
            mImageView.setImageBitmap(null);
            return;
        }

        //EXIF 可交换的图像文件格式
        try {
            ExifInterface ei = new ExifInterface(imageFilePath);
            String modelAttribute = ei.getAttribute(ExifInterface.TAG_MODEL);
            String makeAttribute = ei.getAttribute(ExifInterface.TAG_MAKE);
            String timeAttribute = ei.getAttribute(ExifInterface.TAG_DATETIME);
            if (modelAttribute != null && makeAttribute != null){
                mExifDescTextView.setText(String.format("%s %s %s", makeAttribute, modelAttribute, timeAttribute));
            }else{
                mExifDescTextView.setText("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        Log.d("dhy", imageFilePath);
        BitmapFactory.Options bmpFactoryOptions = getBitmapOptions();
        Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
        mImageView.setImageBitmap(bmp);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值