I am using blow post to work with camera API, and flip camera to back/front.
Fliping the Front Camera to Back Camera in Button Click using android
In samsung device by default it open the camera preview in landscape but
camera.setDisplayOrientation(90);
by this code i am able to open camera preview in portrait. but while i am saving the image it is saving it in landscape Automatically.
by using this approch
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap,
curntViewWidth, curntViewHeight, true);
processing speed is slow down. Do any one have any other way by which camera preview,capture and save image orientation will be same ..
Do we have any library to open camera and set image in specific size like this app
https://play.google.com/store/apps/details?id=com.tinypiece.android.mlc
From the docs of Camera.Parameters#setRotation():
If applications want to rotate the picture to match the orientation of
what users see, apps should use OrientationEventListener and
Camera.CameraInfo
public void onOrientationChanged(int orientation) {
if (orientation == ORIENTATION_UNKNOWN) return;
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
orientation = (orientation + 45) / 90 * 90;
int rotation = 0;
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
rotation = (info.orientation - orientation + 360) % 360;
} else { // back-facing camera
rotation = (info.orientation + orientation) % 360;
}
mParameters.setRotation(rotation);
}
OrientationEventListeneris an abstract class that contains the onOrientationChanged(). This method will receive orientation changes from the system. This is one possible implementation:
OrientationEventListener listener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int i) {
//Code from above goes here.
}
};
listener.enable();
Related
Scenario :
The photo rotated 90 degrees when the picture was taken from the iPhone camera and uploaded on the server and trying to load the same photo on android device.
What I found so far is Meta information(EXIF data) is ignored by the Android system before downloading the image. When photo uploaded from iPhone, the EXIF information of that particular photo is something like this: orientation 6 Rotated 90 CCW, but when it comes to android this value becomes: orientation 0(UNDEFINED)
I tried a couple of approaches but did not work, let me know if anyone faced similar issue or any solution or work around for this, Thanks in advance.
Sample snippet code :
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 4;
resultBitmap = decodeStream(inputStream, null, bmOptions);
ExifInterface exif = new ExifInterface(inputStream);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle);
Bitmap rotated = Bitmap.createBitmap(resultBitmap,0,0,resultBitmap.getWidth(),resultBitmap.getHeight(),matrix,true);
if(rotated != null){
resultBitmap = rotated;
}
enter code here
This question already has answers here:
How to detect when the device switch from portrait to landscape mode? [duplicate]
(4 answers)
Closed 4 years ago.
I am making an application in which I have to take a picture every one second in a service without launching the camera preview.
I wrote the following code in service and able to take picture.
if (cameraId < 0) {
Log.d(TAG, "No camera found");
}
else
{
camera = Camera.open(cameraId);
camera.startPreview();
}
camera.takePicture(null, null, bitmapHandler);
In the bitmapHandler class I get the capture image data in
#Override
public void onPictureTaken(byte[] data, Camera camera) {
.
.
.
}
when I take the picture in portrait mode, the resultant image is rotated by 90 degree clockwise.
when I take the picture in landscape mode, the resultant image is proper.
when I take the picture in reverse-landscape mode, the resultant image is rotated by 180 degree
when I take the picture in reverse-portrait mode, the resultant image is rotated by 270 degree
What i did to get proper image so that I can feed that image to my neural network.
What I tried : I am rotating the bitmap by 90 when image was taken in portrait mode, but still not able to find in which mode the image was captured.
Does the Camera API have any way to know or control the rotation angle ?
I was using the function fixImageOrientation, parameters are image itself and path to the image file (as second parameter, I was passing the path where camera activity stores temporary image file)
public static Bitmap rotateImage(Bitmap bmp, float angle)
{
Matrix matrix = new Matrix();
matrix.postRotate(angle);
System.out.println("Rotating image " + Float.toString(angle) + " degrees, rotateImage()");
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
}
public static Bitmap fixImageOrientation(Bitmap bmp, String path)
{
ExifInterface ei;
boolean changed = true;
try {
ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
bmp = rotateImage(bmp, 90);
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
bmp = rotateImage(bmp, 180);
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
bmp = rotateImage(bmp, 270);
else
changed = false;
} catch (IOException e){
System.out.println("IOException, image probably has no exif data, fixImageOrientation()");
e.printStackTrace();
}
if (changed)
{
System.out.println("Image orientation fixed, fixImageOrientation()");
}
else
{
System.out.println("Image orientation did not change, fixImageOrientation()");
}
return bmp;
}
I want to rotate bitmap when the picture taken as potrait .
I want to understand image is potrait or lanscape?
I use this code :
Bitmap photo = BitmapFactory.decodeFile(path_img,options);
int imageHeight = photo.getHeight();
int imageWidth = photo.getWidth();
When I take image as portroit and lanscape it does not matter it is always like this :
imageHeight =390; imageWidth =520;
How can I understand a picture is taken lanscape or portrait.
Thanks
Code taken from nigels link and altered it for the provided code snippet
Bitmap photo = BitmapFactory.decodeFile(path_img,options);
ExifInterface exif = new ExifInterface(path_img);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
Matrix matrix = new Matrix();
if (rotation != 0f) {
matrix.preRotate(rotationInDegrees);
}
Bitmap adjustedBitmap = Bitmap.createBitmap(photo, 0, 0, width, height, matrix, true);
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }
return 0;
}
from what i understood, this code snippet and the 2 methods should do all the work by themselfs.
How can I understand a picture is taken lanscape or portrait?
assuming the image is currently stored on file, you can get it orientation from the Exif metadata object:
File f = new File(capturedImageFilePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
note that this information not necessarily available - it's up to the application which captured the image to store this metadata on the file.
in case this information not exists, getAttributeInt would return ExifInterface.ORIENTATION_NORMAL
the orientation can can be one of the following: ExifInterface.ORIENTATION_ROTATE_90 / ExifInterface.ORIENTATION_ROTATE_180 / ExifInterface.ORIENTATION_ROTATE_270
I've written an app to capture an image. The problem is that the image is rotated 90 degrees after the capture. I've setted the
camera.setDisplayOrientation(NINTY_DEGREES);
But this only affects the previewing of the SurfaceView. The real problem is that the bytes I get from the camera is flipped. Why does this happend? Is there a setting I can set to flip it before capture?
I my activity subcribes to an event, when the image is captured. This is how I register when the byte[] is filled:
camera.takePicture(null, null, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (null != callback)
callback.onJpegPictureTaken(data, camera);
}
});
In my Activity
public class History extends BaseWindow implements OnClickListener, CaptureImageCallback
and the relevant method:
#Override
public void onJpegPictureTaken(byte[] data, Camera camera) {
Intent i = new Intent(this, ImageEditing.class);
i.putExtra("image", data);
startActivity(i);
}
You can see the parameter data which contains the image data, this byte array is rotated 90 degress. I could of course rotate the ImageView 90 degress, but since I will work with other systems, such as a homemade webservice, I would need to apply this hot fix to every external system. How can I correct this rotation?
Thanks!
You can get the "Angle" of your captured image and rotate as per angle.
ExifInterface exif = new ExifInterface(imagePath);
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;
}
Log.d("Tag", "Angle: " + angle);
Matrix mat = new Matrix();
mat.postRotate(angle);
if (angle != 0)
Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), mat, true);
As name indicates setDisplayOrientation() is for display only. Doc says:
This does not affect the order of byte array passed in
onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos
So if you want to save rotated image, you need to rotate it yourself prior saving.
This question already has answers here:
Why does an image captured using camera intent gets rotated on some devices on Android?
(23 answers)
Closed 4 years ago.
I have had a look around but there doesn't seem to be a solid answer/solution to the, very irritating, problem.
I take a picture in portrait orientation and when I hit save/discard the buttons are in the correct orientation also. The problem is when I then retrieve the image later on it is in landscape orientation (the picture has been rotated 90 degrees anti-clockwise)
I don' want to force the user to use the camera in a certain orientation.
Is there a way to maybe detect whether the photo was taken in portrait mode and then decode the bitmap and flip it the correct way up?
The picture is always taken in the orientation the camera is built into the device. To get your image rotated correctly you'll have to read the orientation information that is stored into the picture (EXIF meta data). There it is stored how the device was oriented, when the image was taken.
Here is some code that reads the EXIF data and rotates the image accordingly:
file is the name of the image file.
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = new ExifInterface(file);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
UPDATE 2017-01-16
With the release of the 25.1.0 Support Library, an ExifInterface Support Library was introduced, which should perhaps make the access to the Exif attributes easier. See the Android Developer's Blog for an article about it.
The selected answer uses the most common method answered to this and similar questions. However, it did not work for me with both front and back cameras on Samsung. For those needing another solution which works across both front and back cameras for Samsung and other major manufacturers, this answer by nvhausid is awesome:
https://stackoverflow.com/a/18915443/6080472
For those who don't want to click through, the relevant magic is to use the CameraInfo rather then relying on EXIF or a Cursor over the media files.
Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
Bitmap bitmap = rotate(realImage, info.orientation);
Full code in the link.