【问题标题】:android - custom camera common solutionandroid - 自定义摄像头常用解决方案
【发布时间】:2014-04-28 13:58:57
【问题描述】:

我正在实现自定义相机。它工作正常,但在某些手机中,尤其是在少数三星手机中,我们面临一些问题,比如将图像保存为旋转。假设我们以纵向模式拍摄照片,但图像以横向模式保存。

这里我有一些疑问。

  1. 我将相机屏幕活动方向设置为纵向。是否会产生任何问题。哪个方向适合有摄像头的活动。
  2. 针对所有手机的图像旋转和预览拉伸问题的常见解决方案是什么。

我尝试了很多。我的解决方案仅在 nexus、Moto G 等少数手机上运行。它在 Samsung S4 mini、Galaxy Grand Duos 2 中失败......

谢谢,

【问题讨论】:

    标签: android android-camera


    【解决方案1】:

    我实现了一个拍照活动,您可以拍照并设置照片的方向。我测试的每台设备都支持它,包括三星 Galaxy 系列、平板电脑、索尼 xperia 系列、平板电脑。

    您可以查看我接受的关于此主题的图像旋转的答案:

    Camera capture orientation on samsung devices in android

    这部分是我在主要活动中将拍摄的照片设置为图像视图的地方:

                try {
                    File imageFile = new File(cursor.getString(0));
                    ExifInterface exif = new ExifInterface(
                            imageFile.getAbsolutePath());
                    int orientation = exif.getAttributeInt(
                            ExifInterface.TAG_ORIENTATION,
                            ExifInterface.ORIENTATION_NORMAL);
                    switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        rotate = 270;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        rotate = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        rotate = 90;
                        break;
                    }
    
                    Log.v("", "Exif orientation: " + orientation);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Matrix matrix = new Matrix();
                matrix.postRotate(rotate);
                bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
                testImage.setImageBitmap(null);
                testImage.setImageBitmap(bmp);
    

    相机活动中的常量值:

      private static final int ORIENTATION_PORTRAIT_NORMAL =  1;
      private static final int ORIENTATION_PORTRAIT_INVERTED =  2;
      private static final int ORIENTATION_LANDSCAPE_NORMAL =  3;
      private static final int ORIENTATION_LANDSCAPE_INVERTED =  4;
      private OrientationEventListener mOrientationEventListener;
      private int mOrientation =  -1;
    

    相机活动中的回调函数:

          Camera.PictureCallback photoCallback=new Camera.PictureCallback(){
              public void onPictureTaken(final byte[] data, final Camera camera){
    
                  dialog=ProgressDialog.show(CameraActivity.this,"","Please wait while the photo is being saved..");
                  new Thread(){
                      public void run(){
                          try{
                              Thread.sleep(1000);         
                          }
                          catch(Exception ex){}
                          onPictureTake(data,camera);     
                      }
                  }.start();      
              }
          };
    

    相机活动中的拍照功能:

          public void onPictureTake(byte[] data, Camera camera){
              switch (mOrientation) {
              case ORIENTATION_PORTRAIT_NORMAL:
                  rotate = 90;
                  break;
              case ORIENTATION_LANDSCAPE_NORMAL:
                  rotate = 0;
                  break;
              case ORIENTATION_PORTRAIT_INVERTED:
                  rotate = 270;
                  break;
              case ORIENTATION_LANDSCAPE_INVERTED:
                  rotate = 180;
                  break;
              }
    
              Matrix matrix = new Matrix();
              matrix.postRotate(rotate);
              bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
              bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
              mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
              savePhoto(mutableBitmap);
              dialog.dismiss();
              flag = 0;
              finish();
          }
    

    在相机活动的 onresume 中调用的方向监听器:

    mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
    
                    @SuppressWarnings("deprecation")
                    @Override
                    public void onOrientationChanged(int orientation) {
    
                        // determine our orientation based on sensor response
                        int lastOrientation = mOrientation;
    
                        Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();   
                        int rotation = getWindowManager().getDefaultDisplay().getRotation();
                        System.out.println(rotation+"");
    
                    if (display.getOrientation() != Surface.ROTATION_0) {   // landscape oriented devices
                            System.out.println("LANDSCAPE");
                            if (orientation >= 315 || orientation < 45) {
                                if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {                         
                                    mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
                                }
                            } else if (orientation < 315 && orientation >= 225) {
                                if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {
                                    mOrientation = ORIENTATION_PORTRAIT_INVERTED;
                                }                       
                            } else if (orientation < 225 && orientation >= 135) {
                                if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {
                                    mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
                                }                       
                            } else if (orientation <135 && orientation > 45) { 
                                if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {
                                    mOrientation = ORIENTATION_PORTRAIT_NORMAL;
                                }                       
                            }                       
                        } else {  // portrait oriented devices
                            System.out.println("PORTRAIT");
                            if (orientation >= 315 || orientation < 45) {
                                if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {                          
                                    mOrientation = ORIENTATION_PORTRAIT_NORMAL;
                                }
                            } else if (orientation < 315 && orientation >= 225) {
                                if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {
                                    mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
                                }                       
                            } else if (orientation < 225 && orientation >= 135) {
                                if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {
                                    mOrientation = ORIENTATION_PORTRAIT_INVERTED;
                                }                       
                            } else if (orientation <135 && orientation > 45) { 
                                if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {
                                    mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
                                }                       
                            }
                        }
    
                    }
                };
    

    如果您还需要保存和使用已旋转的图像,请保存和使用我上面给出的答案以外的照片功能:

    保存照片功能:

    public void savePhoto(Bitmap bmp) {
    
            imageFileFolder = new File(Environment.getExternalStorageDirectory(),
                    cc.getDirectoryName());
            imageFileFolder.mkdir();
            FileOutputStream out = null;
            Calendar c = Calendar.getInstance();
            String date = fromInt(c.get(Calendar.MONTH))
                    + fromInt(c.get(Calendar.DAY_OF_MONTH))
                    + fromInt(c.get(Calendar.YEAR))
                    + fromInt(c.get(Calendar.HOUR_OF_DAY))
                    + fromInt(c.get(Calendar.MINUTE))
                    + fromInt(c.get(Calendar.SECOND));
            imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
            try {
                out = new FileOutputStream(imageFileName);
                bmp.compress(Bitmap.CompressFormat.JPEG, 70, out);
                out.flush();
                out.close();
                scanPhoto(imageFileName.toString());
                out = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    scanPhoto功能:

    public void scanPhoto(final String imageFileName) {
            geniusPath = imageFileName;
            msConn = new MediaScannerConnection(MyClass.this,
                    new MediaScannerConnectionClient() {
                        public void onMediaScannerConnected() {
                            msConn.scanFile(imageFileName, null);
    
                        }
    
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
    
                            msConn.disconnect();
    
                        }
                    });
            msConn.connect();
        }
    

    SavePhotoTask 类:

    class SavePhotoTask extends AsyncTask<byte[], String, String> {
            @Override
            protected String doInBackground(byte[]... jpeg) {
                File photo = new File(Environment.getExternalStorageDirectory(),
                        "photo.jpg");
                if (photo.exists()) {
                    photo.delete();
                }
                try {
                    FileOutputStream fos = new FileOutputStream(photo.getPath());
                    fos.write(jpeg[0]);
                    fos.close();
                } catch (java.io.IOException e) {
                }
                return (null);
            }
        }
    

    【讨论】:

    • 我将清单文件中的活动方向设置为纵向。我可以申报吗?因为我不希望它在风景中。我的意思是在这里我将其限制为纵向。
    • 我的活动也是纵向的
    猜你喜欢
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多