devops 信创在数字经济时代提升企业竞争力的关键策略
707
2022-11-19
android使用自定义相机避开部分小米手机app调用系统相机有水印会转向的问题
1.需求
我们要求很简单,就是拍照后显示效果要横屏拍的横着显示,竖屏拍着竖屏显示。但是我的手机小米5x等小米型号,存在横竖使用系统相机拍摄都是横屏显示的问题。更惨的是获取旋转角度什么的始终是0,没办法弃疗使用自定义相机,顺便可以去掉系统相机的水印。 简单归纳为以下一点: 横竖屏拍摄后,竖屏状态下查看图片始终是正的
2.选材
自己做个相机在我的项目中没有必要,我要的是普通相机,不用美颜高级功能,所以找个好的开源项目然后修改是我的目标。 目前只翻到两个github开源项目符合我的需求: a.JCameraView b.CameraKit
这两个都可以,相对来说JCameraView更细致一些,有一些动画,有对焦功能,所以选用了这个。
3.改造
1.去除顶部栏,把闪光灯功能放在右边
这是JCameraView内的项目图,实际上除了右上角的前置后置镜头切换,右上角还新增了一个闪光灯功能
但我思考了一下,右上角的镜头翻转在我的项目里不需要,直接invisible隐藏了,把闪光灯移动到了拍摄按钮右边,这样使用上更方便简洁一些。
修改了cameraApplication下的布局camera_view.xml
修改后如下:
mCaptureLayout.setRightClickListener(new ClickListener() { @Override public void onClick() {// if (rightClickListener != null) {// rightClickListener.onClick();// }
private void setRightFlashRes() { switch (type_flash) { case TYPE_FLASH_AUTO: mCaptureLayout.setRightResource(R.drawable.ic_flash_auto); machine.flash(Camera.Parameters.FLASH_MODE_AUTO); break; case TYPE_FLASH_ON: mCaptureLayout.setRightResource(R.drawable.ic_flash_on); machine.flash(Camera.Parameters.FLASH_MODE_ON); break; case TYPE_FLASH_OFF: mCaptureLayout.setRightResource(R.drawable.ic_flash_off); machine.flash(Camera.Parameters.FLASH_MODE_OFF); break;
2.去掉录像功能
此相机长按具有录像功能,需对jcamera进行设置: 修改CameraActivity:
jCameraView.setFeatures(JCameraView.BUTTON_STATE_ONLY_CAPTURE);//设置为只能拍照
3.去掉录音权限请求
不用录视频也就用不到录音,需修改MainActivity:
/** * 获取权限 */ private void getPermissions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager .PERMISSION_GRANTED &&// ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager// .PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager .PERMISSION_GRANTED) { startActivityForResult(new Intent(MainActivity.this, CameraActivity.class), 100); } else { //不具有获取权限,需要进行权限申请 ActivityCompat.requestPermissions(MainActivity.this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE,// Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, GET_PERMISSION_REQUEST); } } else { startActivityForResult(new Intent(MainActivity.this, CameraActivity.class), 100); } }
@TargetApi(23) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == GET_PERMISSION_REQUEST) { int size = 0; if (grantResults.length >= 1) { int writeResult = grantResults[0]; //读写内存权限 boolean writeGranted = writeResult == PackageManager.PERMISSION_GRANTED;//读写内存权限 if (!writeGranted) { size++; } //相机权限 int cameraPermissionResult = grantResults[1]; boolean cameraPermissionGranted = cameraPermissionResult == PackageManager.PERMISSION_GRANTED; if (!cameraPermissionGranted) { size++; } if (size == 0) { startActivityForResult(new Intent(MainActivity.this, CameraActivity.class), 100); } else { Toast.makeText(this, "请到设置-权限管理中开启", Toast.LENGTH_SHORT).show(); } } } }
4.自动对焦
这里提一点,因为VideoView这个控件有点奇葩,或者说手机厂商原因,此控件上方下方必须都有遮盖物(要有宽高),不然中间放置的对焦框就可能会在某些位置时不可见。 以下全部为修改JCameraView.java 首先,此对焦框需要对焦可见:
//对焦框指示器动画 private void setFocusViewWidthAnimation(float x, float y) { if(mPhoto.getVisibility() != View.VISIBLE) mFoucsView.setVisibility(View.VISIBLE); machine.foucs(x, y, new CameraInterface.FocusCallback() { @Override public void focusSuccess() { mFoucsView.setVisibility(INVISIBLE); } }); }
@Override public void showPicture(Bitmap bitmap, boolean isVertical) { if (isVertical) { mPhoto.setScaleType(ImageView.ScaleType.FIT_XY); } else { mPhoto.setScaleType(ImageView.ScaleType.FIT_CENTER); } captureBitmap = bitmap; mPhoto.setImageBitmap(bitmap); mPhoto.setVisibility(VISIBLE); mFoucsView.setVisibility(INVISIBLE); mCaptureLayout.startAlphaAnimation(); mCaptureLayout.startTypeBtnAnimator();
@Override public boolean handlerFoucs(float x, float y) { if (y > mCaptureLayout.getTop()) { return false; } if (x < mFoucsView.getWidth() / 2) { x = mFoucsView.getWidth() / 2; } if (x > layout_width - mFoucsView.getWidth() / 2) { x = layout_width - mFoucsView.getWidth() / 2; } if (y < mFoucsView.getWidth() / 2) { y = mFoucsView.getWidth() / 2; } if (y > mCaptureLayout.getTop() - mFoucsView.getWidth() / 2) { y = mCaptureLayout.getTop() - mFoucsView.getWidth() / 2; } if(mPhoto.getVisibility() != View.VISIBLE) mFoucsView.setVisibility(View.VISIBLE); mFoucsView.setX(x - mFoucsView.getWidth() / 2); mFoucsView.setY(y - mFoucsView.getHeight() / 2); ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFoucsView, "scaleX", 1, 0.6f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFoucsView, "scaleY", 1, 0.6f); ObjectAnimator alpha = ObjectAnimator.ofFloat(mFoucsView, "alpha", 1f, 0.4f, 1f, 0.4f, 1f, 0.4f, 1f); AnimatorSet animSet = new AnimatorSet(); animSet.play(scaleX).with(scaleY).before(alpha); animSet.setDuration(400); animSet.start(); return true;
这里判断了mPhotoView,mPhotoView是拍摄完成后用来显示拍摄结果的,当显示拍摄结果的时候,按道理说应该不可见对焦框,所以关掉。
然后我们使用Handler来进行定时对焦,这里我取的是5秒:
public void onResume() { LogUtil.i("JCameraView onResume"); resetState(TYPE_DEFAULT); //重置状态 CameraInterface.getInstance().registerSensorManager(mContext); CameraInterface.getInstance().setSwitchView(mSwitchCamera, mFlashLamp); machine.start(mVideoView.getHolder(), screenProp); if(handler == null){ handler = new MyHandler(this); } handler.sendEmptyMessage(1); } private MyHandler handler; //生命周期onPause public void onPause() { LogUtil.i("JCameraView onPause"); stopVideo(); resetState(TYPE_PICTURE); CameraInterface.getInstance().isPreview(false); CameraInterface.getInstance().unregisterSensorManager(mContext); if(handler!=null) handler.removeCallbacksAndMessages(null); }
2.0f; focusy = getScreenHeight()/2.0f;
private float getScreenHeight(){ WindowManager manager = ((Activity)getContext()).getWindowManager(); DisplayMetrics outMetrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.heightPixels; } private float getScreenWidth(){ WindowManager manager = ((Activity)getContext()).getWindowManager(); DisplayMetrics outMetrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(outMetrics); return
onTouchEvent->ACTION_DOWN添加:
event.getX(); focusy = event.getY();
handler:
public static class MyHandler extends Handler{ private WeakReference
这里我定的是5秒,你可以根据自己的需求修改为合适的时间
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~