精华内容
下载资源
问答
  • 安卓应用原生相机

    2013-08-16 11:51:21
    原生相机,仅供刷机的人放入app中,刷入这个可以全景摄像!带来完美感受。 童鞋们赶快下载吧!原生相机有时候白平衡/自动对焦会出现问题。似乎索尼的对焦经常在快拍模式下失灵!经过一段时间使用,找到了2个最适合...
  • 最近一直在学习RN的相关开发,想做一部分调用原生的实现,来练练手,于是就有了下面这个demo,由于本人是Android开发,所以只实现了Android端的效果. Demo    主要实现 这种调用原生的操作,主要涉及到RN于原生交互...

    前言

    最近一直在学习RN的相关开发,想做一部分调用原生的实现,来练练手,于是就有了下面这个demo,由于本人是Android开发,所以只实现了Android端的效果.

    Demo   

                                                                             

    主要实现

    这种调用原生的操作,主要涉及到RN于原生交互和通信,官方给出的交互方式就是通过在Application中注册的模式实现交互.

    首先我们需要先创建一个RN项目 CameraPage.js ,并把它设为启动页:页面比较简单,就是两个按钮拍照,照片一个Image标签用来展示原生的图片.开始新建与原生交互的类, CameraMoudle 继承自ReactContextBaseJavaModule类:

    public class CameraMoudle extends ReactContextBaseJavaModule {
        private ReactApplicationContext reactContext;
        public CameraMoudle(ReactApplicationContext reactContext) {
            super(reactContext);
            this.reactContext =reactContext;
        }
    
        @Override
        public String getName() {
            return "CameraMoudle";
        }
        //打开登录设置界面,用于给RN调用
        @ReactMethod
        public void openNative(int tag) {
            Intent intent = new Intent();
            CameraAct.reactContext=reactContext;
            CameraAct.tag=tag;
            intent.setClass(reactContext, CameraAct.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            reactContext.startActivity(intent);
        }
    }

    这个getName()方法中返回的就是RN端调用的引用名,相当于webview中addJavascriptInterface(JsInterface,JsName)中的JsName,下面的openNative方法是我们自定义的Rn端调用原生的方法.注意:这里面的reactContext是静态赋值.接下来创建CameraPackage.java继承ReactPackage这个CameraMoudle需要通过这个类在Application中注册才能使用:

    public class CameraPackage implements ReactPackage {
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList<>();
            modules.add(new CameraMoudle(reactContext));
            return modules;
        }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return  Collections.emptyList();
        }
    }

    在Application中新增标识的代码

     @Override
        protected List<ReactPackage> getPackages() {
          return Arrays.<ReactPackage>asList(
              new MainReactPackage(),
                  new CameraPackage()//新增包操作
          );
        }

    新建一个空Activity  CameraAct.java,用来执行,跳转相机和相册的逻辑操作,由于不需要界面所有就不用setContentView啦!

    拍照和相册相关操作:

    private void choosePhoto() {
            Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null);
            intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg");
            startActivityForResult(intentToPickPic, PHOTO_REQUEST_CODE);
        }
    
    
        private void takePhoto() {
            // 跳转到系统的拍照界面
            Intent intentToTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 指定照片存储位置为sd卡本目录下
            mPhotoPath = Environment.getExternalStorageDirectory() + File.separator + "photo.jpeg";
            // 获取图片所在位置的Uri路径 由于使用的tagBuildVersion 26需要通过内容提供者获取文件写入操作
            mImageUri = FileProvider.getUriForFile(this,
                    getApplicationContext().getPackageName() + ".my.provider",
                    new File(mPhotoPath));
            //下面这句指定调用相机拍照后的照片存储的路径
            intentToTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
            startActivityForResult(intentToTakePhoto, CAMERA_REQUEST_CODE);
        }
    
        //当拍摄照片完成时会回调到onActivityResult 在这里处理照片的裁剪
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode == RESULT_OK) {
                switch (requestCode) {
                    case CAMERA_REQUEST_CODE: {
                        sendToRn();
                        break;
                    }
                    case PHOTO_REQUEST_CODE: {
                        Uri mImageUri=data.getData();
                        if (!TextUtils.isEmpty(mImageUri.getAuthority())) {
                            String[] proj = {MediaStore.Images.Media.DATA};
                            Cursor cursor = managedQuery(mImageUri, proj, null, null,
                                    null);
                            int column_index = cursor
                                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                            cursor.moveToFirst();
                            mPhotoPath = cursor.getString(column_index);
                        }else{
                            mPhotoPath= mImageUri.getPath();
                        }
    
                        sendToRn();
                        break;
                    }
                    default:
                        break;
                }
            }
            super.onActivityResult(requestCode, resultCode, data);
        }

    由于我本地  targetSdkVersion为26 所以需要动态申请权限和通过内容提供者获取文件读取操作(如果使用 22 版本就都不需要啦!)

    private boolean checkPermission(){
                String [] permissions =new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA
                };
            for (String permission:permissions) {
                if (ContextCompat.checkSelfPermission(CameraAct.this, permission) != PackageManager.PERMISSION_GRANTED){
                    ActivityCompat.requestPermissions(CameraAct.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
                            tag==0?CAMERA_REQUEST_CODE:PHOTO_REQUEST_CODE);
                    return false;
                }
            }
            return true;
        }
    
     @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                switch (requestCode) {
                    case CAMERA_REQUEST_CODE:
                        takePhoto();
                        break;
                    case PHOTO_REQUEST_CODE:
                        choosePhoto();
                        break;
                    default:
                        break;
                }
    
            } else {
                Toast.makeText(this, "一些权限被禁止", Toast.LENGTH_SHORT).show();
            }
    
        }

    入口调用方法

      private void startCamera() {
            if(checkPermission()){
                if (tag==0) {
                    takePhoto();
                }else {
                    choosePhoto();
                }
            }
        }

    为了防止静态赋值的reactContext内存泄露:

       @Override
        protected void onDestroy() {
            super.onDestroy();
            reactContext=null;
        }

    差点忘了权限添加:

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.CAMERA" />

    内容提供者:临时权限配置

      <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="${applicationId}.my.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths"/>
            </provider>

    android/src/main/res下新建xml文件夹 创建provider_paths.xml

    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
    </paths>

    至此android端的配置已经完成,接下来修改RN端代码:CameraPage.js增加以下代码:

      getPhoto=(statusCode)=>{
            //调用原生
            CameraMoudle.openNative(statusCode);
            //注册监听
            DeviceEventEmitter.addListener("photo", (params) => {
                let index =params.indexOf('storage');
                let file='file:///'+params.substr(index==-1?1:index);
                this.setState({
                    imgFile:file
                })
            });
    
        }

    statusCode是用来区分照相和相册选择的,通用处理了一下,Image标签:

    <View style={{alignItems:'center'}}>
        {this.state.imgFile===''?null:<Image style={{width:width/2,height: height/2}} source={{uri:this.state.imgFile}}/>}
    </View>

    以上调用就可以实现Rn调用原生的操作.

     

    另外

    RN与原生交互的方式有3中:RCTDeviceEventEmitter,Callback,Promise;其中第一种方式是唯一一种原生主动发送消息给RN的.

    另外两种都是RN端作为主动方,原生被动返回.

    以上如有疏漏的地方,望不吝赐教.

     

    展开全文
  • android 调用原生相机

    千次阅读 2016-10-17 11:21:18
    * 为选择的模式设置intent参数,调用系统相机 系统相册 系统裁剪 * @param type GALLERY CAMERA PHOTO_REQUEST_CUT * */ private void setPhotoIntent ( int type) { Intent intent = new Intent(); ...

    GitHub

    public class MeFragment extends BaseFragment implements View.OnClickListener {
    
        private String TAG = getClass().getSimpleName();
        private ImageView ivPhoto;
    
        private static final int CAMERA = 1;// 拍照
        private static final int GALLERY = 2;// 从相册中选择
        private static final int PHOTO_REQUEST_CUT = 3;// 结果
        private final String IMAGE_FILE_LOCATION = Environment.getExternalStorageDirectory() + "/temp.jpg"; //temp file
    
        private AlertDialog dialog;
        private View dialogView;
        private View backgroundView;
        private boolean isBackground;
    
        public static MeFragment newInstance(String param1, String param2) {
            MeFragment fragment = new MeFragment();
            Bundle args = new Bundle();
            return fragment;
        }
    
        @Override
        protected void initView() {
            backgroundView=bind(R.id.ivPhotoBg);
            ivPhoto = bind(R.id.ivPhoto);
            dialogView=LayoutInflater.from(getActivity()).inflate(R.layout.dialog_select_image,null);
    
            String uri = ShareUtils.getPhotoUri();
            String uriBackground=ShareUtils.getPhotoBackground();
            if(!TextUtils.isEmpty(uri)){
                ivPhoto.setImageURI(Uri.parse(uri));
            }
            if(!TextUtils.isEmpty(uriBackground)){
                setBackground(Uri.parse(uriBackground));
            }
            dialog = new AlertDialog.Builder(getActivity(), R.style.fullScreen).create();
            initListener(this,R.id.ivPhoto,R.id.ivPhotoBg);
            initListener(this,dialogView.findViewById(R.id.btCamera),dialogView.findViewById(R.id.btPhoto),dialogView.findViewById(R.id.btCancel));
        }
    
        @Override
        public int getRootLayoutId() {
            return R.layout.fragment_me;
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btCamera:
                    setPhotoIntent(CAMERA);
                    break;
                case R.id.btPhoto:
                    setPhotoIntent(GALLERY);
                    break;
                case R.id.ivPhoto:
    
                    isBackground=false;
                    dialog.setCancelable(true);
                    dialog.show();
                    dialog.setContentView(dialogView);
                    break;
                case R.id.ivPhotoBg:
                    isBackground=true;
                    dialog.setCancelable(true);
                    dialog.show();
                    dialog.setContentView(dialogView);
                    break;
            }
        }
    
        /**
         * 为选择的模式设置intent参数,调用系统相机 系统相册 系统裁剪
         * @param type GALLERY CAMERA PHOTO_REQUEST_CUT
         * */
        private void setPhotoIntent(int type) {
            Intent intent = new Intent();
            switch (type) {
                case PHOTO_REQUEST_CUT:
                    break;
                case GALLERY:
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    intent.setType("image/*");
                    startActivityForResult(intent, GALLERY);
                    break;
                case CAMERA:
                    Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(camera, CAMERA);
                    break;
            }
        }
    
        /**
         * 调用系统裁剪功能:
         * 传入图片uri
         * @param uri picture uri
         */
        private void startPhotoZoom(Uri uri) {
            Log.i(TAG, " url================" + uri);
    
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(uri, "image/*");
            // crop为true是设置在开启的intent中设置显示的view可以剪裁
            intent.putExtra("crop", "true");
            // aspectX aspectY 是宽高的比例
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
    
            // outputX,outputY 是剪裁图片的宽高
            intent.putExtra("outputX", 600);
            intent.putExtra("outputY", 600);
            intent.putExtra("return-data", true);
            intent.putExtra("noFaceDetection", true);
            startActivityForResult(intent, PHOTO_REQUEST_CUT);
        }
    
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            Log.i(TAG, String.format("request code = %d result code = %d   data is null %b", requestCode, resultCode, data == null));
    
            if(dialog!=null){
                dialog.dismiss();
            }
    
            if (resultCode != Activity.RESULT_OK || data == null) {
                Toast.makeText(getActivity(), "you have cancel option", Toast.LENGTH_SHORT).show();
                return;
            }
    
            switch (requestCode) {
                case CAMERA:// 当选择拍照时调用
                    if(isBackground){
                        setBackground(data.getData());
                    }else{
                        startPhotoZoom(data.getData());//相册返回uri丢给系统裁剪
                    }
                    break;
                case GALLERY:// 当选择相册时
                    if(isBackground){
                        setBackground(data.getData());
                        Log.i(TAG,data.getDataString());// uri content://com.android.providers.media.documents/document/image%3A32507
                        ShareUtils.setPhotoBackground(data.getDataString());
                    }else{
                        startPhotoZoom(data.getData());//相册返回uri丢给系统裁剪
                    }
                    break;
                case PHOTO_REQUEST_CUT:// 返回的结果
                    Bitmap bitmap = data.getParcelableExtra("data");//裁剪后,取出bitmap界面显示
                    ShareUtils.setPhotoUri(IMAGE_FILE_LOCATION);
                    saveBitmap(bitmap);
                    ivPhoto.setImageBitmap(bitmap);
                    break;
            }
    
        }
    
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        private void setBackground(Uri uri) {
            InputStream inputStream;
            Drawable drawable=null;
            try {
                Log.i(TAG," uri "+uri);
                 inputStream = getActivity().getContentResolver().openInputStream(uri);
                drawable=Drawable.createFromStream(inputStream,"dataString");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            if(drawable!=null){
                backgroundView.setBackground(drawable);
                Log.d(TAG,"set ok");
            }else{
                Log.e(TAG,"setBackground error");
            }
        }
    
        /**
         * 把头像保存在本地
         * @param bm
         * @return
         */
        private Uri saveBitmap(Bitmap bm) {
            File tmpDir = new File(IMAGE_FILE_LOCATION);
            tmpDir.delete();
            if (!tmpDir.getParentFile().exists()) {
                tmpDir.mkdir();
            }
            File img = new File(IMAGE_FILE_LOCATION);
            try {
                FileOutputStream fos = new FileOutputStream(img);
                bm.compress(Bitmap.CompressFormat.PNG, 85, fos);
                fos.flush();
                fos.close();
                Toast.makeText(getActivity(), "保存成功了", Toast.LENGTH_SHORT).show();
                return Uri.fromFile(img);
            } catch (FileNotFoundException e) {
                Toast.makeText(getActivity(), "保存失败", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(getActivity(), "保存失败", Toast.LENGTH_SHORT).show();
                return null;
            }
        }
    
        /**
         * 1、bitmap  to  uri
         * <p/>
         * Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null,null));
         * <p/>
         * 2、uri  to  bitmap
         * <p/>
         * Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
         * 读取图片属性:旋转的角度
         *
         * @param path 图片绝对路径
         * @return degree旋转的角度
         */
        public static int readPictureDegree(String path) {
            int degree = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(path);
                int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return degree;
        }
    
        /**
         * 旋转图片
         *
         * @param angle
         * @param bitmap
         * @return Bitmap
         */
        public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
            //旋转图片 动作
            Matrix matrix = new Matrix();
            matrix.postRotate(angle);
            System.out.println("angle2=" + angle);
            // 创建新的图片
            Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                    bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            return resizedBitmap;
        }
    }
    
    展开全文
  • android启动相机三种方式

    热门讨论 2013-04-11 19:50:23
    基于android 2.3.3 三种调用相机的方式 分别为使用android自带的照相功能 指定存储目录 使用SurfaceHolder预览相机的图片
  • 这是一个示例,展示了如何在Android平台上使用Flint协议和WebRTC库来做相机镜像。 如何使用 下载源代码 使用Eclipse编译位于sender目录下的 Android sender 应用程序。 在应该有摄像头(一两个)的 Android 移动...
  • Android自定义相机demo-手动触摸对焦、取景模式、白平衡、曝光补偿、闪关灯、分辨率设置、视频拍摄、拉近等功能。包含Android4.1原生相机所有功能。
  • Android相机开发

    千次阅读 2019-03-21 00:29:02
    在activity中添加添加偏好设置预览分辨率预览格式照片分辨率图片格式视频分辨率对焦模式曝光补偿闪光灯模式白平衡场景声明GPS权限代码如下拍照,视频,对焦相机预览和保存注意事项参考 Android相机开发 申请权...

    Android相机开发

    申请权限

    <uses-permission android:name="android.permission.CAMERA" />
    <!--可以防止APP被安装到没有相机的Android设备上(目前仅Google Play支持)-->
    <uses-feature android:name="android.hardware.camera" />
    

    动态权限不要忘了

    创建一个可以预览的界面

    1.创建一个新工程

    2.在新创建的工程中activity中布局文件

    <FrameLayout
        android:id="@+id/preview_f"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    

    3.创建一个相机预览的view 继承SurfaceView

    最新都开始用TextureView,关于SurfaceView/TextureView

    • SurfaceView是一个有自己Surface的View。界面渲染可以放在单独线程而不是主线程中。它更像是一个Window,自身不能做变形和动画。
    • TextureView同样也有自己的Surface。但是它只能在拥有硬件加速层层的Window中绘制,它更像是一个普通View,可以做变形和动画。

    更多关于SurfaceView与TextureView区别的内容可以参考这篇文章Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView.

    官方给出的方案,图片来自于Android平台Camera开发实践指南:

    官方给出的方案

    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    
        private final SurfaceHolder mHolder;
        private Camera mCamera;
    
        public CameraPreview(Context context) {
            super(context);
            mHolder = getHolder();
            mHolder.addCallback(this);
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
        	//surface第一次创建时回调
            //打开相机
            mCamera = Camera.open();
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    		//surface变化的时候回调(格式/大小)
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        	//surface销毁的时候回调
            mHolder.removeCallback(this);
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
    

    4.在activity中添加

    public class MainActivity extends AppCompatActivity {
    
        private FrameLayout mFrameLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initCamera();
        }
    
        private void initCamera() {
            CameraPreview preview = new CameraPreview(this);
            mFrameLayout.addView(preview);
        }
    
        private void initView() {
            mFrameLayout = (FrameLayout) findViewById(R.id.preview_f);
        }
    }
    

    至此可以显示一个相机界面,并有图像显示。

    添加偏好设置

    如分辨率、闪光灯、对焦等。

    通过当前界面的相机camera对象获取起设置的参数getParameters()

    预览分辨率

    • parameters.getSupportedPreviewSizes()获取相机支持的所有预览分辨率

    预览格式

    具体参照ImageFormat或者自己Google

    • parameters.getSupportedPreviewFormats()获取相机支持的所有预览格式

    照片分辨率

    • parameters.getSupportedPictureSizes()获取相机支持的所有图片分辨率

    图片格式

    具体参照ImageFormat或者自己Google

    • parameters.getSupportedPictureFormats()获取相机支持的所有图片格式

    视频分辨率

    parameters.getSupportedVideoSizes()获取相机支持的所有视频分辨率

    对焦模式

    • parameters.getSupportedFocusModes()获取相机支持的所有对焦模式

    曝光补偿

    • parameters.getMinExposureCompensation()获取相机支持的最低曝光补偿
    • parameters.getMaxExposureCompensation()获取相机支持的最高曝光补偿

    闪光灯模式

    • parameters.getSupportedFlashModes()获取相机支持的闪光灯模式

    白平衡

    • parameters.getSupportedWhiteBalance()获取相机支持的白平衡

    场景

    parameters.getSupportedSceneModes()获取相机支持的场景

    声明GPS权限

    想要拍到的照片中包含GPS信息

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

    代码如下

    int numberOfCameras = Camera.getNumberOfCameras();
    Log.d("123===", "相机个数===" + numberOfCameras);
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    for (int i = 0; i < numberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        //后置:0 CAMERA_FACING_BACK; 前置:1 CAMERA_FACING_FRONT
        Log.d("123===", "当前相机信息=" + cameraInfo.facing);
    }
    
    
    Camera camera = mPreview.getCamera();
    Camera.Parameters parameters = camera.getParameters();
    
    Log.d("123===", "预览分辨率-----------");
    List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
    for (Camera.Size previewSize : supportedPreviewSizes) {
        Log.d("123===", previewSize.width + "---" + previewSize.height);
    }
    Log.d("123===", "预览分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "获得相机支持的图片预览格式-----------ImageFormat");
    List<Integer> supportedPreviewFormats = parameters.getSupportedPreviewFormats();
    for (Integer supportedPreviewFormat : supportedPreviewFormats) {
        Log.d("123===", supportedPreviewFormat + "");
    }
    Log.d("123===", "获得相机支持的图片预览格式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "照片分辨率-----------");
    List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
    for (Camera.Size pictureSize : supportedPictureSizes) {
        Log.d("123===", pictureSize.width + "---" + pictureSize.height);
    }
    Log.d("123===", "照片分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "获得相机支持的图片格式-----------ImageFormat");
    List<Integer> supportedPictureFormats = parameters.getSupportedPictureFormats();
    for (Integer supportedPreviewFormat : supportedPictureFormats) {
        Log.d("123===", supportedPreviewFormat + "");
    }
    Log.d("123===", "获得相机支持的图片格式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "视频分辨率-----------");
    List<Camera.Size> supportedVideoSizes = parameters.getSupportedVideoSizes();
    for (Camera.Size supportedVideoSize : supportedVideoSizes) {
        Log.d("123===", supportedVideoSize.width + "---" + supportedVideoSize.height);
    
    }
    Log.d("123===", "视频分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "对焦模式-----------ImageFormat");
    List<String> supportedFocusModes = parameters.getSupportedFocusModes();
    for (String supportedFocusMode : supportedFocusModes) {
        Log.d("123===", supportedFocusMode + "");
    }
    Log.d("123===", "对焦模式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "曝光补偿-----------");
    int minExposureCompensation = parameters.getMinExposureCompensation();
    int maxExposureCompensation = parameters.getMaxExposureCompensation();
    Log.d("123===", "最高=" + maxExposureCompensation);
    Log.d("123===", "最低=" + minExposureCompensation);
    Log.d("123===", "曝光补偿-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "支持闪光灯模式-----------");
    List<String> supportedFlashModes = parameters.getSupportedFlashModes();
    for (String supportedFlashMode : supportedFlashModes) {
        Log.d("123===", "闪光模式--->" + supportedFlashMode);
    }
    Log.d("123===", "支持闪光灯模式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "支持白平衡-----------");
    List<String> supportedWhiteBalance = parameters.getSupportedWhiteBalance();
    for (String s : supportedWhiteBalance) {
        Log.d("123===", "--->" + s);
    }
    Log.d("123===", "支持白平衡-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "场景-----------");
    List<String> supportedSceneModes = parameters.getSupportedSceneModes();
    for (String s : supportedSceneModes) {
        Log.d("123===", "--->" + s);
    }
    Log.d("123===", "场景-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    

    拍照,视频,对焦

    假如需要使用原生拍照功能的话,Camera#takePicture()

    拍照和视频都是网上那一套流程,具体的因为时间原因暂时先这样了。

    相机预览和保存注意事项

    下面三张图片引用自:Android: Camera相机开发详解(中) ——实现预览、拍照、保存照片等功能

    • 相机预览方向

    相机预览方向

    • 采集的图像方向

    采集的图像方向

    • 前置摄像头预览与保存一致

    前置摄像头预览与保存一致

    参考

    展开全文
  • Unity技术分享之与原生交互IOS端无法获取相机权限问题 前提条件: 输出IOS包的流程是Unity导出Xcode工程后拷贝Native, Data/ Library三个文件夹至原生Xcode工程; 最近遇到一个问题就是, 在项目中因为要用到相机渲染...

    Unity技术分享之与原生交互IOS端无法获取相机权限问题

    前提条件: 输出IOS包的流程是Unity导出Xcode工程后拷贝Native, Data/ Library三个文件夹至原生Xcode工程;

    最近遇到一个问题就是, 在项目中因为要用到相机渲染在屏幕显示, 用的webcam 在安卓上权限获取和显示都没有问题 , 但是在IOS上说什么都不行(权限获取弹窗可以正常弹出, 但就是HasUserAuthorization返回的值是false。

    先说原因:
    1. 因为Unity每次导出Xcode工程的时候会检测是否有相关权限调用的代码, 如果有在Xcode工程下的Classes/Preprocessor.h文件中会预定义权限宏处理. 相关定义如下:

    // The following UNITY_USES_* flags disable functionality in the trampoline project
    // whenever the user does not use it from his scripts. We detect the API usage and
    // adjust the value of these flags whenever the project is built (including when the
    // project is appended)
    // 通知权限
    #define UNITY_USES_REMOTE_NOTIFICATIONS 0
    // 相机权限
    #define UNITY_USES_WEBCAM 0
    // 麦克风权限
    #define UNITY_USES_MICROPHONE 0
    // 录屏权限
    #define UNITY_USES_REPLAY_KIT 0
    // 快照权限(程序暂停时候快照)
    #define UNITY_SNAPSHOT_VIEW_ON_APPLICATION_PAUSE 0
    // 工程模式
    #define UNITY_DEVELOPER_BUILD 0
    // 动态链接库
    #define UNITY_USES_DYNAMIC_PLAYER_LIB 0
    // 定位
    #define UNITY_USES_LOCATION 0
    

    value是0的表示关闭相关权限 , 这时候Unity会检测不到相关权限的获取, 手动把0改为1标明权限开放.
    重新打包即可.

    展开全文
  • 之前为了体验「MIUI 12」使用了内测版,越用越卡,特别是动画掉帧,真是受不了,回想当年用「NEXUS 5」的安卓原生系统那个流畅啊。所以昨晚果断就刷了类原生安卓固件「Pixel Experience」非常流畅,动画从不掉帧,...
  • 原生微信小程序

    千次阅读 2020-02-22 08:46:58
    微信小程序 ... 小程序代码构成 JSON 配置 WXML 模版 WXSS 样式 JS 逻辑交互 JSON 配置 在小程序中,JSON扮演的静态配置的角色。... "pages": ["pages/index/index", "pages/logs/logs"], "window...
  • 竞品分析:美颜相机VS轻颜相机——关于美颜相机未来产品规划的思考 美颜相机最早发布于2013年,相比于行业同类产品起步比较早,市场占有率也很高。轻颜相机是脸萌旗下的一款产品,发布于2018年,发展十分迅猛,在APP...
  • 安卓4.1系统里的相机,但好像还多一种功能,全景模式可以360度,超级全景图
  • react-native 之与"android原生模块"交互

    千次阅读 2018-06-14 23:27:42
    react-native 之与android原生交互
  • 今天我们按步骤完成一个自定义相机的制作。 1.Camera相关的API 拍照我们主要用到的两个类,一个是SurfaceView,这个我们在上一次就介绍过了;还有一个就是Camera了。所以我们需要了解一下Camera相关API。 ...
  • 一、初始化vue脚手架  注:安装完vue环境之后(vue环境配置,网上找) ...利用webpack模式,myvue-----&gt;vue项目名称。 2、初始化完成之后,可使用npm run dev在开发模式进行运行。 二、初始化cor...
  • 小程序的发布,让我们...” 首先我们来看看原生APP,从2010年正式崛起,对开发者而言,不过两三年的时候,对企业而言,更是赖以进入互联网时代的标志,正因如此,不论是隶属于信息服务范畴的IT软硬件开发商或是内容
  • 原生页面和H5页面

    千次阅读 2018-08-23 15:42:11
    原生应用”占统治地位  当我们为移动设备开发应用程序时,程序员通常都会选择开发“原生应用”,“原生应用”是一种用户必须通过手机应用商店购买下载并安装在手机存储器内的应用程序。“原生应用”现已成为新增...
  • 原生应用开发,是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发。比如android是利用java、eclipse、Android studio,IOS是利用Objective-C 和Xcode进行开发。原生应用由于利用...
  • 一、今天,来介绍如何调用系统自带的相机进行拍照,主要有以下2种实现的方式: 1、Camera应用程序包含了一个意图过滤器,即intent filter,它使得开发人员能够提供与Camera应用程序同等的图像捕获能力,因此我们...
  • 页面元素如果是一整块的是h5的,布局密密麻麻的是原生控件。 2. 看加载的方式 -(比较准确) 如过在打开新页面导航栏下面有一条加载条的话,这个页面就是H5页面,如果没有就是原生的。 3.看断网的情况 把手机的网络断...
  • GoogleCamera代码流程分析之相机切换

    千次阅读 2017-08-30 22:02:28
    最近一直在看GoogleCamera的代码,虽然是google...由于GoogleCamera在相机的预览、拍照录像方面均使用了Camera API2的接口,不熟悉这个接口使用的开发人员可能连开始预览的接口都找不到(还是习惯了使用Camera API1)。
  • 相机常用术语解释

    千次阅读 2017-05-25 13:53:46
    相机常用术语解释
  • H5和原生APP之间的区别

    千次阅读 2018-10-08 11:03:15
    不过好在现在非原生APP同样可以调用蓝牙、相机等硬件,也能顺利发布到苹果APP store。 移动Web App  1、因为运行在移动设备的浏览器上,所以只需要一个开发项目  2、这种应用可以使用HTML5,CSS3以及...
  • H5开发是Html5开发的app,本质上运行在手机浏览器中的页面,一般使用app做一个壳套用浏览器运行H5的页面,由于H5的特性也有很多app使用半原生半H5的hybird app 开发模式。react-native是用react 进行原生app开发的...
  • cordova通过原生实现自定义功能

    万次阅读 2016-10-04 13:38:15
    先闲谈说下最近的微信要出的小程序吧,感觉确实很牛逼,革命说不上吧但是也是一个新的大的机遇。不得不承认腾讯有两个相当好的平台,一个是QQ,一个是微信,毕竟人数基数大,任何新的东西... 最近研究cordova通过原生
  • 蓝牙模块:启动相机 window.WebViewJavascriptBridge.callHandler(  , ’StarXgzCamera‘  , {'mode' : ‘需要输入的盖章模式(0/1)’,'surplusFre' : ‘需要输入的剩余可盖章次数’}  ,...
  • android自定义相机拍照

    千次阅读 2017-10-17 09:32:29
    android自定义相机拍照
  • 如何区分手机端 APP 是原生 APP 还是 H5? 1.如果断开网络,立即显示 404 或者页面错误基本上是 H5 2.通过查看页面布局边界,操作步骤 a.手机设置,开发者选项里去开启,打开页面布局开关,b.然后进入 APP 里查看...
  • 近些年,随着移动互联网和移动设备的普及,基于原生环境的移动端开发方兴未艾。同时,Web开发者也不甘寂寞。基于移动端浏览器开发可自适应多屏幕的Web应用自然而然地出现了,各类已有网站迅速被移动化了。此时的Web...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,793
精华内容 1,917
关键字:

原生模式相机