39

フロントエンドカメラとバックエンドカメラの両方から写真を撮るポートレートモードのカメラアプリがあります.SDカードに画像を保存し、常に0を与える対応するexif値を見つけようとしています.しかし、予想されるexif方向を取得していますデバイスに保存されている他の画像 (ダウンロードした画像など) の値。

どうすればこれを修正できますか? 誰でも私を助けることができますか?

写真を保存して向きを見つけるために使用されるコードは次のとおりです

PictureCallback myPictureCallback_JPG = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub


                try {
                    File APP_FILE_PATH = new File(Environment.getExternalStorageDirectory()
                            .getPath() + "/Myapp/");
                    if (!APP_FILE_PATH.exists()) {
                        APP_FILE_PATH.mkdirs();
                    }
                    File file = new File(APP_FILE_PATH, "image.jpg");

                    FileOutputStream fos = new FileOutputStream(file);
                    fos.write(arg0);
                    fos.close();
imageFileUri=Uri.fromfile(file);                           getApplicationContext().getContentResolver().notifyChange(
                          imageFileUri, null);
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                            Uri.parse("file://"
                                    + Environment.getExternalStorageDirectory())));
                    ExifInterface exif = new ExifInterface(file.getAbsolutePath());
                    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);



                } catch (Exception e) {

                }



    }
};

以下は、サーフェスの作成および変更された関数のコードです。

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);

camera.setParameters(parameters);
camera.startPreview();
 startPreview();

}
 @Override
 public void surfaceCreated(SurfaceHolder holder) {


 try {

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
          Camera.CameraInfo info=new Camera.CameraInfo();

          for (int i=0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, info);

            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
              camera=Camera.open(i);
              defaultCameraId = i;
            }
          }
        }

        if (camera == null) {
          camera=Camera.open();
        }




        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Camera.Parameters parameters = camera.getParameters();
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(defaultCameraId, info);
        int rotation = this.getWindowManager().getDefaultDisplay()
                .getRotation();
        if (Integer.parseInt(Build.VERSION.SDK) >= 8)
        {

             int degrees = 0;
             switch (rotation) {
                 case Surface.ROTATION_0: 
                     degrees = 0; break;
                 case Surface.ROTATION_90: 
                     degrees = 90; break;
                 case Surface.ROTATION_180: 
                     degrees = 180; break;
                 case Surface.ROTATION_270: 
                     degrees = 270; break;
             }
             int result;
             if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                 result = (info.orientation + degrees) % 360;
                 result = (360 - result) % 360;  
             } else {  // back-facing
                 result = (info.orientation - degrees + 360) % 360;
             }
             camera.setDisplayOrientation(result);

        }
        else
        {
            parameters.set("orientation", "portrait");
        }


        camera.setParameters(parameters);



} catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} 


}
 private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.1;
            double targetRatio = (double) w / h;
            if (sizes == null) return null;

            Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = h;


            for (Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }


            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }
4

4 に答える 4

24

Samsung デバイスでも同じ問題に直面しましたが、後でExifInterfaceを実装して問題を解決しました。

どのモードでも、画像は常にポートレート モードでのみ保存され、取得中もポートレート モードで返されます。以下のコードは、目標を達成するために使用したもので、バックカメラ内に実装しましたが、カメラからはわかりません。

カメラの意図@

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(intent, 1212);   

onActivityResult@

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 1212) {
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
        Bitmap bitmap;
        //bitmap=GlobalMethods.decodeSampledBitmapFromResource(_path, 80, 80);
        bitmap=GlobalMethods.decodeFile(_path);
        if (bitmap == null) {
            imgMed.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.add_photo));
        } 
        else {
            imgMed.setImageBitmap(bitmap);
            imgMed.setScaleType(ScaleType.FIT_XY);

        }
    }
        }

デコードファイル@

    public static Bitmap decodeFile(String path) {

          int orientation;

             try {

                 if(path==null){

                     return null;
                 }
                 // decode image size
                 BitmapFactory.Options o = new BitmapFactory.Options();
                 o.inJustDecodeBounds = true;

                 // Find the correct scale value. It should be the power of 2.
                 final int REQUIRED_SIZE = 70;
                 int width_tmp = o.outWidth, height_tmp = o.outHeight;
                 int scale = 4;
                 while (true) {
                     if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                         break;
                     width_tmp /= 2;
                     height_tmp /= 2;
                     scale++;
                 }
                 // decode with inSampleSize
                 BitmapFactory.Options o2 = new BitmapFactory.Options();
                 o2.inSampleSize=scale;
                 Bitmap bm = BitmapFactory.decodeFile(path,o2);


                 Bitmap bitmap = bm;

                 ExifInterface exif = new ExifInterface(path);
                 orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
                 Log.e("orientation",""+orientation);
                 Matrix m=new Matrix();

                 if((orientation==3)){

                 m.postRotate(180);
                 m.postScale((float)bm.getWidth(), (float)bm.getHeight());

//               if(m.preRotate(90)){
                 Log.e("in orientation",""+orientation);

                 bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
                 return  bitmap;
                 }
                 else if(orientation==6){

                  m.postRotate(90);

                  Log.e("in orientation",""+orientation);

                  bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
                     return  bitmap;
                 }

                 else if(orientation==8){

                  m.postRotate(270);

                  Log.e("in orientation",""+orientation);

                  bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
                     return  bitmap;
                 }
                 return bitmap;
             }
             catch (Exception e) {
             }
             return null;
         }
于 2012-11-12T08:00:57.147 に答える
3

問題は、exif 情報を手動で関数に入れなければならないことですonPictureTaken

画像 (jpg) を保存したら、Exif インターフェイスを作成して、自分でパラメーターを配置する必要があります。

....
exif = new ExifInterface(file.getAbsolutePath());
exif.setAttribute(ExifInterface.TAG_ORIENTATION, orientation_detected_by_you_application);
exif.saveAttributes();

あなたの携帯電話にある他の写真は、撮影した写真にexif情報を入れるアプリケーションで作られています.

向きを検出するには:

public void enableOrientationListener(){

    if (mOrientationEventListener == null) {            
        mOrientationEventListener = new OrientationEventListener(getContext(), SensorManager.SENSOR_DELAY_NORMAL) {

            @Override
            public void onOrientationChanged(int orientation) {

                // determine our orientation based on sensor response
                int lastOrientation = mOrientation;

                Display display = null;
                if(parentActivity == null){
                    display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
                }else{
                    display = parentActivity.getWindowManager().getDefaultDisplay();
                }


                if (display.getOrientation() == Surface.ROTATION_0) {   // landscape oriented devices
                    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
                    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;
                        }                       
                    }
                }
            }
        };
    }
    if (mOrientationEventListener.canDetectOrientation()) {
        mOrientationEventListener.enable();
    }
}


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;


public void disableOrientationListener(){
    if(mOrientationEventListener != null){
        mOrientationEventListener.disable();
    }
}

mOrientationまた、画像の方向属性として設定する必要があります。

于 2012-11-10T16:52:31.273 に答える
0

での例外を無視しています:

    try {
        // Code
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    } catch (Exception e) {

    }

試す :

    try {
        // Code
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    } catch (Exception e) {
        e.printStackTrace();
    }

そしてlogcatを投稿してください。例外を破棄することは決して賢明ではありません。

于 2012-11-09T07:25:44.897 に答える