自定义简易相机

自定义简易相机及图片的二次采样

在开发中,APP中经常会有一个这样的一个界面点击照相跳转手机相机界面,但是由于手机型号特别多,由于许多第三方厂商对底层源码做了很多改变,跳转手机系统相机的时候会有出现崩溃、BUG,下面我们可以自己写一个相机,去跳转我们自定义的相机
这里写代码片
xml文件

activity_main.xml
<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="拍照"
    android:onClick="click1"
    android:id="@+id/takepicture"/>
<ImageView
    android:layout_width="match_parent"
    android:id="@+id/iv"
    android:layout_height="match_parent"/>

carera.xml

<Button
android:layout_width="match_parent"
android:text="确定"
android:onClick="onClick"
android:layout_height="wrap_content"/>
<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

MainActivity
照相获得图片有可能会很大 ,或造成OOM(内存溢出)在这里我对图片做了处理进行了二次采样,

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView=(ImageView) findViewById(R.id.iv);
}
public void click1(View view){
    Intent intent  = new Intent(this,MyCamera.class);
    startActivityForResult(intent,100);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode==100&&resultCode==RESULT_OK&&data!=null){
        String path = data.getStringExtra("path");
        Log.i("自定义标签", "onActivityResult: "+path);
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        imageView.setImageBitmap(bitmap);
    }
}

}
Mycamera

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);
    surface = (SurfaceView) findViewById(R.id.surfaceView);
    SurfaceHolder holder = surface.getHolder();//获得界面的持有者
    holder.addCallback(this);//大的控件初始化需要时间,异步操作
}

public void onClick(View view) {
    camera.takePicture(new Camera.ShutterCallback() {
        @Override
        public void onShutter() {//按下快门

        }
    }, new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            //返回一张原始图片raw格式

        }
    }, new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                //返回一张压缩后的图片jpeg,返回的图片有可能还会很大,我们将对他进行二次采样,进行压缩避免OOM(内存溢出)
                Matrix m = new Matrix();
                m.setRotate(90);
                //Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
                //将图片的名称转换为日期格式
                SimpleDateFormat Dataformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date currentDate = new Date();
                String stringDate = Dataformat.format(currentDate);
                //将data数组写入到指定路劲下
                File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/" + stringDate + ".jpeg");
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(data,0,data.length);
                fos.close();
                //获取屏幕的宽高的分辨率
                WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
                DisplayMetrics metrics = new DisplayMetrics();
                manager.getDefaultDisplay().getMetrics(metrics);
                //将图片进行压缩
                rarBitmap(file.getAbsolutePath(),metrics.widthPixels,metrics.heightPixels );

                Intent intent = new Intent();
                intent.putExtra("path", file.getAbsolutePath());
                Log.i("自定义标签", "onPictureTaken: " + file.getAbsolutePath());
                setResult(RESULT_OK, intent);
                finish();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * 压缩图片
 *
 * @param picPath    原始图片的路径
 * @param wandWidth  期望的宽度
 * @param wandHeight 期望的高度
 * @return
 */

public Bitmap rarBitmap(String picPath, int wandWidth, int wandHeight) {
    Bitmap bewBitmap = null;
    BitmapFactory.Options ops = new BitmapFactory.Options();//创建图片时候的选项
    ops.inJustDecodeBounds = true;//进入仅编码模式,只获取元数据 不真正加载图片
    BitmapFactory.decodeFile(picPath, ops);//这行代码执行完毕, 会将图片的元数据放到 ops 里面
    int height = ops.outHeight;//获取原始图片的高度
    int width = ops.outWidth;//宽度
    int scalx = (int) (((float) width) / wandWidth + 0.6f);//计算一个宽度的压缩比
    int scaly = (int) (((float) height) / wandHeight + 0.6f);//计算一个高度的压缩比
    //因为期望的宽高度的比例 和原始的宽高度可能不一致,所以我们应该以一个方向为准,防止图片压缩后变形,两个压缩值以谁大取谁
    int scale = scalx > scaly ? scalx : scaly;
    ops.inSampleSize = scale;
    //重新加载图片,首先推出仅编码模式
    ops.inJustDecodeBounds = false;
    bewBitmap = BitmapFactory.decodeFile(picPath, ops);
    return bewBitmap;


}
/**
 * 在这初始化相机
 *
 * @param holder
 */
@Override
public void surfaceCreated(SurfaceHolder holder) {

    try {
        camera = Camera.open();//打开相机
        camera.setPreviewDisplay(holder);//设置预览
        camera.setDisplayOrientation(90);//因为默认横屏,所以旋转90度
        camera.startPreview();//启动预览

    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * 状态发生了改变
 *
 * @param holder
 * @param format
 * @param width
 * @param height
 */
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

/**
 * 销毁的时候把相机释放掉,要不然别的地方会打不开相机
 *
 * @param holder
 */
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    camera.release();//释放相机
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值