1

I wrote this camera app, but I cannot got correct image on every device

I found that there are two types camera on different devices, so I cannot rotate photo correctly on every device.

I have looked into some open source camera app, but don't see any logic to handle this problem, and these apps still rotate correctly.

How to detect the type of camera? so that I can rotate photo to correct degree.

enter image description here

public class Camera01 extends Activity implements SurfaceHolder.Callback {
    SurfaceHolder surfaceHolder;
    SurfaceView surfaceView1;
    Button button1;
    Camera camera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera01);
        button1=(Button)findViewById(R.id.button1);
        surfaceView1=(SurfaceView)findViewById(R.id.surfaceView1);
        surfaceHolder=surfaceView1.getHolder();
        surfaceHolder.addCallback(this);
        button1.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                camera.autoFocus(afcb);
            }
        });
    }
    PictureCallback jpeg =new PictureCallback(){
        public void onPictureTaken(byte[] data, Camera camera) {
            new SaveImageTask().execute(data);
            camera.startPreview();
        }
    };
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
    public void surfaceCreated(SurfaceHolder holder) {
        camera=Camera.open(1);
        try {
            Camera.Parameters params = camera.getParameters();
            List<Camera.Size> sizes = params.getSupportedPictureSizes();
            params.setPictureFormat(PixelFormat.JPEG);
            Camera.Size mSize = sizes.get(0);
            params.setPictureSize(mSize.width, mSize.height);
            params.setRotation(90);  //  <<<<<<<<<<<<<<<<<<<<< to correct photo direction
            camera.setParameters(params);
            camera.setPreviewDisplay(surfaceHolder);
//            camera.setDisplayOrientation(90);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
    }
    AutoFocusCallback afcb= new AutoFocusCallback(){
        public void onAutoFocus(boolean success, Camera camera) {
            if(success){
                camera.takePicture(null, null, jpeg);
            }
        }
    };

    private class SaveImageTask extends AsyncTask<byte[], Void, Void> {
        @Override
        protected Void doInBackground(byte[]... data) {
            FileOutputStream outStream = null;
            try {

                File dir = new File(Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_DCIM), "test");
                if (! dir.exists()){
                    if (! dir.mkdirs()){
                        Log.d("MyCameraApp", "failed to create directory");
                        return null;
                    }
                }

                String fileName = String.format("%d.jpg", System.currentTimeMillis());
                File outFile = new File(dir, fileName);

                outStream = new FileOutputStream(outFile);
                outStream.write(data[0]);
                outStream.flush();
                outStream.close();
                Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                mediaScanIntent.setData(Uri.fromFile(outFile));
                sendBroadcast(mediaScanIntent);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            return null;
        }

    }
}
CL So
  • 3,647
  • 10
  • 51
  • 95
  • 1
    Please check http://stackoverflow.com/a/13176590/192373. Also, you setRotation(90) - do you expect that the end-user holds the device in portrait upright orientation? You can use orientation sensor to distinguish between portrait and landscape pictures. Also, [setRotation()](http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setRotation(int)) is nothing but a hint, and most cameras will only set an EXIF flag, which is often ignored by picture viewers. – Alex Cohn May 04 '16 at 09:27

1 Answers1

0

You can make correct rotation if you have filepath of image with scaled bitmap of image then use below method:

public Bitmap checkRotation(String filePath, Bitmap scaledBitmap) {
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Log.d("EXIF", "Exif: " + orientation);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                    true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return scaledBitmap;
    }
Pankaj
  • 7,908
  • 6
  • 42
  • 65
  • I just tried, this is not work, it just remove exif rotation information and rotate jpeg data, not handle the difference between different devices. If the information is wrong, I still rotate incorrectly. – CL So May 04 '16 at 08:25
  • If you need to rotate the image correctly then above code work for sure, I didnt get it what exactly you need – Pankaj May 04 '16 at 09:06