Android调用相机拍照,压缩图片后保存SD卡中

最近在搞一个项目,需求是调用系统相机拍完照片后保存本地,再上传至后台服务器,但为了节省流量需要压缩上传,将图片压缩至100K以内。这个是在特定机器上运行,类似于手持POS机,但是它的相机几乎没有优化,对焦慢,而且拍照也不清晰,使用自己的手机调用系统相机拍照后图片大概有300K左右,自动已经压缩了,但这个机器没有优化,调用相机拍照后的图片和原图一样2M左右,太大了,必须要压缩!
网上找了些资料,也作为参考:Android图片压缩 质量压缩和尺寸压缩安卓相机拍摄照片,压缩后存储于SD卡
项目需要的效果为:

上代码:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;


public class MainActivity extends Activity implements OnClickListener{

    private Button openCamera,openCamera2;
    private ImageView showImgView;

    Uri photoUri;
    String filePath;  //图片路径

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findView();

    }

    private void findView() {
        // TODO Auto-generated method stub
        openCamera = (Button) findViewById(R.id.openCamera);
        openCamera2 = (Button) findViewById(R.id.openCamera2);
        showImgView = (ImageView) findViewById(R.id.showImgView);
        openCamera.setOnClickListener(this);
        openCamera2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()){
        case R.id.openCamera:
            //打卡相机前先检测SD卡是否可以用
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                photoUri = patrUri("file1");
                startCamera(1001,photoUri);
            }else{
                Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show();
            }
            break;
        case R.id.openCamera2:
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                photoUri = patrUri("file2");
                startCamera(1002,photoUri);
            }else{
                Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show();
            }
            break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 1001){
            if(resultCode == RESULT_OK){
                FileInputStream is = null;
                try {
                    is = new FileInputStream(filePath);
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    showImgView.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        if(requestCode == 1002){
            if(resultCode == RESULT_OK){

                try {
                    Bitmap bitmap = compressBySize(filePath,480,800);  //设置压缩后图片的高度和宽度
                    saveFile(bitmap,filePath);
                    showImgView.setImageBitmap(bitmap);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }


    // 压缩图片尺寸
    private static Bitmap compressBySize(String pathName, int targetWidth,
            int targetHeight) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;// 不去真的解析图片,只是获取图片的头部信息,包含宽高等;
        Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts);
        // 得到图片的宽度、高度;
        float imgWidth = opts.outWidth;
        float imgHeight = opts.outHeight;
        // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于等于该比例的最小整数;
        int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);
        int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);
        opts.inSampleSize = 1;
        if (widthRatio > 1 || widthRatio > 1) {
            if (widthRatio > heightRatio) {
                opts.inSampleSize = widthRatio;
            } else {
                opts.inSampleSize = heightRatio;
            }
        }
        // 设置好缩放比例后,加载图片进内容;
        opts.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(pathName, opts);
        return bitmap;
    }

    //保存压缩后的图片
    private void saveFile(Bitmap bitmap, String filePath2) throws IOException {
        // TODO Auto-generated method stub
        File testFile = new File(filePath2);
        if (testFile.exists()) {
            testFile.delete();
        }

        File myCaptureFile = new File(filePath2);
        System.out.println("------filePath2==" + filePath2);
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(myCaptureFile));
        // 100表示不进行压缩,70表示压缩率为30%
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos);
        bos.flush();
        bos.close();
    }

    //打开相机
    private void startCamera(int requestCode, Uri photoUri) {
        // TODO Auto-generated method stub
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri);
        startActivityForResult(intent, requestCode);
    }

    /**
     * 图片保存路径  这里是在SD卡目录下创建了MyPhoto文件夹
     * @param fileName
     * @return
     */
    private Uri patrUri(String fileName) {  //指定了图片的名字,可以使用时间来命名
        // TODO Auto-generated method stub
        String strPhotoName = fileName+".jpg";              
        String savePath = Environment.getExternalStorageDirectory().getPath()
                + "/MyPhoto/";
        File dir = new File(savePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        filePath = savePath + strPhotoName;
        return Uri.fromFile(new File(dir, strPhotoName));
    }
}

页面布局很简单,就两个Button跟一个ImageView,这里就不贴代码了。
效果图片:
这里写图片描述
SD卡中的图片:
这里写图片描述
可以看到,file2.jpg是压缩过的,file1.jpg是原图,因为是模拟器,效果不太明显,在真机上压缩后的图片在100K之内。

要调用相机和读写SD卡,最后不要忘了加权限。

代码下载
因为工作的原因,这里使用的是Myeclipse不过Eclipse也可以用。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值