amrit singh amrit singh - 5 months ago 7
Java Question

Hello i have a issue with this example

I'm posting the example and it makes a photo and let you see the preview but i have a problem: The issue is that if you try this code you'll see the preview but it is not oriented correctly please is there someone who can solve this?

public class MainActivity extends ActionBarActivity {

private ImageSurfaceView mImageSurfaceView;
private Camera camera;

private FrameLayout cameraPreviewLayout;
private ImageView capturedImageHolder;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

cameraPreviewLayout = (FrameLayout)findViewById(R.id.camera_preview);
capturedImageHolder = (ImageView)findViewById(R.id.captured_image);

camera = checkDeviceCamera();
mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
cameraPreviewLayout.addView(mImageSurfaceView);

Button captureButton = (Button)findViewById(R.id.button);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
}
});
}
private Camera checkDeviceCamera(){
Camera mCamera = null;
try {
mCamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}

PictureCallback pictureCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if(bitmap==null){
Toast.makeText(MainActivity.this, "Captured image is empty", Toast.LENGTH_LONG).show();
return;
}
capturedImageHolder.setImageBitmap(scaleDownBitmapImage(bitmap, 300, 200 ));
}
};

private Bitmap scaleDownBitmapImage(Bitmap bitmap, int newWidth, int newHeight){
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
return resizedBitmap;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}


ImageSurfaceView Class

public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

private Camera camera;
private SurfaceHolder surfaceHolder;

public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.camera.stopPreview();
this.camera.release();
}
}


XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:baselineAligned="false">

<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="300dp"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/capture_button"
android:id="@+id/button"
android:layout_below="@+id/camera_preview"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp" />

<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/captured_image"
android:layout_below="@+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="15dp"
android:contentDescription="@string/desc" />




The issue is that if you try this code you'll see the preview but it is not oriented correctly please is there someone who can solve this?

Answer

You have to user Exifinterface and Matrix to get the right orientation. try this:

 public static void handleImageRotation(Context context, File mFileTemp) {

    if (!mFileTemp.exists()) {
        Toast.makeText(context, "File not found", Toast.LENGTH_SHORT).show();
        return;
    }


    ExifInterface exif = null;
    int orientation = ExifInterface.ORIENTATION_NORMAL;
    try {
        exif = new ExifInterface(mFileTemp.getAbsolutePath());

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

    Bitmap temp = BitmapFactory.decodeFile(mFileTemp.getAbsolutePath());

    if (temp == null) Log.e(TAG, "Bitmap from File is null");

    Matrix matrix = new Matrix();

    if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
        matrix.postRotate(90);
        temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
    } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
        matrix.postRotate(180);
        temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
    } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
        matrix.postRotate(270);
        temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
    }

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    temp.compress(Bitmap.CompressFormat.JPEG, 40, bos);

    byte[] bitmapdata = bos.toByteArray();

    // write the bytes in file
    try {
        FileOutputStream fos = new FileOutputStream(mFileTemp);
        fos.write(bitmapdata);
        fos.flush();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}