I made a simple camera application with android. But there is one problem that I cannot solve. My camera app's surfaceView is in portrait mode , however, when I take the image and save the image in the folder. It's not saved in a portrait mode. Since, I'm new to android development I would need some help. I've put some code below.
PictureCallback jpegCallback = new PictureCallback() {
#SuppressWarnings("deprecation")
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
Calendar c = Calendar.getInstance();
File videoDirectory = new File(path);
if (!videoDirectory.exists()) {
videoDirectory.mkdirs();
}
try {
// Write to SD Card
outStream = new FileOutputStream(path + c.getTime().getSeconds() + ".jpg");
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Bitmap realImage;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
options.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
options.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
realImage = BitmapFactory.decodeByteArray(data,0,data.length,options);
ExifInterface exif = null;
try {
exif = new ExifInterface(path + c.getTime().getSeconds()
+ ".jpg");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Log.d("EXIF value",
exif.getAttribute(ExifInterface.TAG_ORIENTATION));
if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("1")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("8")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("3")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("0")) {
realImage = rotate(realImage, 90);
}
} catch (Exception e) {
}
image.setImageBitmap(realImage);
fotoButton.setClickable(true);
camera.startPreview();
progressLayout.setVisibility(View.GONE);
exitButton.setClickable(true);
}
};
public static Bitmap rotate(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}
try below methods some times some device have orientantion roated to 90 or 180 or 270 here is the methods try this to get image in normal mode if its gets rotated:
public static Bitmap RotateImage(String imagePath, boolean rotateImage) {
Matrix imageMatrix = new Matrix();
if (rotateImage) {
int rotationNeeded = getImageRotationDegrees(imagePath);
if (rotationNeeded != 0) {
imageMatrix.postRotate(rotationNeeded);
}
}
public static int getImageRotationDegrees(String imagePath) {
int currentRotation = getImageOrientation(imagePath);
switch (currentRotation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
}
return 0;
}
public static int getImageOrientation(String imagePath) {
ExifInterface exifInterface;
try {
exifInterface = new ExifInterface(imagePath);
} catch (IOException e) {
return ExifInterface.ORIENTATION_UNDEFINED;
}
return exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
}
Related
I am facing a problem while capturing images using intent. The captured image is automatically rotated.
How to prevent the problem. Can someone help?
I hope my solution would still help,
byte[] data = null;
Bitmap bitmap = BitmapFactory.decodeByteArray(fileBytes, 0, fileBytes.length);
ByteArrayOutputStream outputStream = null;
try {
bitmap = ImageResizer.rotateImageIfRequired(bitmap, context, uri);
outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
data = outputStream.toByteArray();
} catch (IOException e) {
Timber.e(e.getMessage());
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
// Intentionally blank
}
}
return data;
}
public static Bitmap rotateImageIfRequired(Bitmap img, Context context, Uri selectedImage) throws IOException {
if (selectedImage.getScheme().equals("content")) {
String[] projection = { MediaStore.Images.ImageColumns.ORIENTATION };
Cursor c = context.getContentResolver().query(selectedImage, projection, null, null, null);
if (c.moveToFirst()) {
final int rotation = c.getInt(0);
c.close();
return rotateImage(img, rotation);
}
return img;
} else {
ExifInterface ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Timber.d("orientation: %s", orientation);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
}
private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
return rotatedImg;
}
I'm creating android camera app. This is an custom camera using camera API.
Whenever I take picture from camera it always save in landscap mode.
I'm using this method to set the camera orientation.
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
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; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
Here is code which is responsible to store image.
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
This code save the image successfully but always in landscape mode. What I'm missing I'm new in android. I want to save image as like it is shown in preview.
Update 2 (According To Answer)
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
int rotationAngle = getCorrectCameraOrientation (MainActivity.this, info);
Toast.makeText(MainActivity.this, "Angle "+ rotationAngle, Toast.LENGTH_SHORT).show();
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
try {
writeFile (data, pictureFile);
} catch (IOException e) {
e.printStackTrace();
}
processImage (pictureFile, rotationAngle, 1);
}
};
I'm using code in this way but this is not working still same problem image is always in landscape mode.
Try
1. First of all, add methods (writeFile, processImage and getCorrectCameraOrientation) defined below (After step 3)
2. Calculate camera orientation after capturing photo and update onPictureTaken**
#Override
public void onPictureTaken (final byte[] data, final Camera camera) {
int rotationAngle = getCorrectCameraOrientation (this, info);
3. Create file and update photo angle using rotationAngle
File file = new File (folder, fileName);
try {
file.createNewFile ();
}
catch (IOException e) {
e.printStackTrace ();
}
writeFile (data, file);
processImage (file, rotationAngle, compressRatio);
writeFile
public static void writeFile (byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream (file);
bos = new BufferedOutputStream (fos);
bos.write (data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
processImage
public static void processImage (File file, int rotationAngle, int compressionRatio) {
BufferedOutputStream bos = null;
try {
Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());
Matrix matrix = new Matrix ();
matrix.postRotate (rotationAngle);
bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);
FileOutputStream fos = new FileOutputStream (file);
bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
}
catch (IOException e) {
e.printStackTrace ();
}
catch (OutOfMemoryError t) {
t.printStackTrace ();
}
catch (Throwable t) {
t.printStackTrace ();
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getCorrectCameraOrientation
public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {
int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
int degrees = 0;
if (hasValidRotation (rotation)) {
degrees = rotation * 90;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == getActivity().RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
String wholeID = DocumentsContract.getDocumentId(filePath);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
uploadFilePath = cursor.getString(columnIndex);
uploadFilePath = decodeFile(uploadFilePath, 512, 512);
}
cursor.close();
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), filePath);
if(sendImageType.equals("profile")){
imgProfile.setImageBitmap(bitmap);
}
else if(sendImageType.equals("cover")){
imgCover.setImageBitmap(bitmap);
}
pDialog = ProgressDialog.show(getActivity(), "", "Uploading file...", true);
new Thread(new Runnable() {
public void run() {
uploadFile(uploadFilePath);
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Decode File :
private String decodeFile(String path,int DESIREDWIDTH, int DESIREDHEIGHT) {
String strMyImagePath = null;
Bitmap scaledBitmap = null;
try {
// Part 1: Decode image
Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
// Part 2: Scale image
scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingUtilities.ScalingLogic.FIT);
} else {
unscaledBitmap.recycle();
return path;
}
// Store to tmp file
String extr = Environment.getExternalStorageDirectory().toString();
File mFolder = new File(extr + "/TMMFOLDER");
if (!mFolder.exists()) {
mFolder.mkdir();
}
String s = "tmp.png";
File f = new File(mFolder.getAbsolutePath(), s);
strMyImagePath = f.getAbsolutePath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
scaledBitmap.recycle();
} catch (Throwable e) {
}
if (strMyImagePath == null) {
return path;
}
return strMyImagePath;
}
Hi, i have an image uploader, i am uploading image from android gallery to my server. But some photos load horizontally. How can i understand, photo is horizontal or vertical and how do i rotate.
It look below, after upload :
to check the orientation of an image
ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
break;
case ExifInterface.ORIENTATION_ROTATE_180:
break;
// etc.
}
To rotate the image use
private Bitmap rotateImage(Bitmap source, float angle) {
Bitmap bitmap = null;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
} catch (OutOfMemoryError err) {
err.printStackTrace();
}
return bitmap;
}
try this code:
public static Bitmap getOriententionBitmap(String filePath){
Bitmap myBitmap = null;
try
{
File f = new File(filePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
Bitmap bmp1 = BitmapFactory.decodeStream(new FileInputStream(f), null, null);
myBitmap = Bitmap.createBitmap(bmp1, 0, 0, bmp1.getWidth(), bmp1.getHeight(), mat, true);
}
catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
}
catch(OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
return myBitmap;
}
Android Saved Images into Gallery not Correctly Oriented
The value obtained after int getOrientationFromExif() is always the same: 1...
Don't know how to solve....
Please help me!
Can you help me to solve? The problem is inside
private PictureCallback mPicture = new PictureCallback()
{
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
#Override
public void onPictureTaken(byte[] data, Camera camera){
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
Bitmap myBitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
myBitmap = rotateImage(getOrientationFromExif(pictureFile), myBitmap);
myBitmap.compress(Bitmap.CompressFormat.JPEG, 70 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
fos = new FileOutputStream(pictureFile);
fos.write(bitmapdata);
fos.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
}
catch(FileNotFoundException e)
{
Log.d(TAG, "File not found: "+e.getMessage());
}
catch(IOException e)
{
Log.d(TAG, "Error accessing file: "+e.getMessage());
}
}
};
public Bitmap rotateImage(int angle, Bitmap bitmapSrc)
{
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(bitmapSrc, 0, 0,
bitmapSrc.getWidth(), bitmapSrc.getHeight(), matrix, true);
}
public int getOrientationFromExif(File imagePath)
{
int orientation = -1;
try
{
ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath());
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
System.out.println("yuri"+exifOrientation);
switch (exifOrientation)
{
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
orientation = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
orientation = 0;
break;
default:
break;
}
} catch (IOException e) {
Log.e(TAG, "Unable to get image exif orientation", e);
}
return orientation;
}
public static boolean isSdPresent() {
return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
}
private static File getOutputMediaFile(int type){
File mediaFile = null;
if(isSdPresent() == false)
{
Log.d(TAG, "There is no Sd card. Cannot use the camera");
}
else
{
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),".");
if(!mediaStorageDir.exists())
{
if(!mediaStorageDir.mkdirs())
{
Log.d("WorldCupApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
if (type == MEDIA_TYPE_IMAGE)
{
mediaFile = new File(mediaStorageDir.getPath() + "IMG_"+ timeStamp + ".JPEG");
}
else
{
return null;
}
}
return mediaFile;
}
ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath());
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Problem is here always is 1 the orientation that means that doesn't need to rotate :(
When you fix your activity to landscape mode for a custom camera implementation the EXIF data will always have ORIENTATION_NORMAL for TAG_ORIENTATION. This is the same side effect that has activity.getWindowManager().getDefaultDisplay().getRotation() always returning ROTATION_90.
I fixed this by detecting the device rotation with an OrientationEventListener and then rewriting the EXIF orientation tag in my onPictureTaken callback to the proper value for the rotation.
Not sure if this behavior is device dependent, this is the behavior on a Galaxy S2 running 4.1.2.
I want to display image in compulsory in portrait after selecting image from Gallery. I am using below code for it.
findViewById(R.id.btn_open_galllery).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent selectPictureIntent = new Intent(
Intent.ACTION_PICK);
selectPictureIntent.setType("image/*");
startActivityForResult(selectPictureIntent, 1212);
}
});
// On Activity Result
Uri selectedImageUri = data.getData();
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
File file = new File(selectedImageUri.getPath());
try {
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.e("Orientation", ""+orientation);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
iv.setImageBitmap(rotatedBitmap);
} catch (IOException e1) {
e1.printStackTrace();
}
// Here i got every time rotation of image, but i want only portrait mode of image if image is in landscape mode.
After selecting the image,forcefully you have to change the orientation of the screen as landscape
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Here is the code to check whether screen is land or port
Configuration newConfig = getResources().getConfiguration();
if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
//PORTRAIT
}else{
//Land
}
Try this
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
if(bitmap.getHeight()< bitmap.getWidth()){
Canvas c = new Canvas(bitmap);
c.rotate(270);
}
// Your rotated image is ready you can use it now
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}