takePicture() landscape mode rotation android - android

I am taking an image from camera using:
mCamera.takePicture(null, null,
new PhotoHandler(getApplicationContext()));
But the image I am taking is landscape and I want it portrait, I tried converting the file into bitmap, rotate it and then save it again, here is my onPictureTaken() function and rotate() function inside PhotoHandler.class:
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d("Error", "Can't create directory to save image.");
Toast.makeText(context, "Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
pictureFile = new File(filename);
st1 = pictureFile.getAbsolutePath();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(context, "New Image saved:" + photoFile,
Toast.LENGTH_LONG).show();
} catch (Exception error) {
Log.d("Error", "File" + filename + "not saved: "
+ error.getMessage());
Toast.makeText(context, "Image could not be saved.",
Toast.LENGTH_LONG).show();
}
Bitmap b = rotate(BitmapFactory.decodeFile(pictureFile.getAbsolutePath()),270);
FileOutputStream out = null;
try {
out = new FileOutputStream(pictureFile);
b.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
CameraPreview.safeToTakePicture = true;
galleryAddPic();
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
Anyway, it takes too long, I tried using mCamera.setDisplayOrientation(90); but it changes only the preview of the camera, the picture taken is still the same, I also tried getting the parameters of the camera and changing it like here:
Camera.Parameters parameters = mCamera.getParameters();
parameters.set("orientation", "portrait");
mCamera.setParameters(parameters);
Without success, any help will be appreciated.
EDIT :
New code:
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Log.d("Error", "Can't create directory to save image.");
Toast.makeText(context, "Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
pictureFile = new File(filename);
st1 = pictureFile.getAbsolutePath();
Bitmap b = rotate(BitmapFactory.decodeByteArray(data,0,data.length),270);
FileOutputStream out = null;
try {
out = new FileOutputStream(pictureFile);
b.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
CameraPreview.safeToTakePicture = true;
galleryAddPic();
}

Anyway, it takes too long
Your current algorithm looks like this:
Start with the photo in memory
Save the photo to disk, which is slow
Read the photo back in from disk to memory, which is slow
Rotate the reloaded photo
A more efficient approach would be:
Start with the photo in memory
Rotate the photo
BitmapFactory has decodeByteArray() to get a Bitmap back for rotation purposes.

Related

How to merge the overlay image with the camera image and save in android?

I have a application that takes photo shots as well as displays a imageview like a frame. What I want to do is to merge the imageview with the data in the PictureCallback, I have read multiple tutorials but I find them difficult. Is it possible to merge and save the image in the code below? Some sample will be helpful!
private Camera.PictureCallback mPicJpgListener = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (data == null) {
return;
}
String saveDir = Environment.getExternalStorageDirectory().getPath() + "/test";
// retrieve the folder
File file = new File(saveDir);
// creating a folder
if (!file.exists()) {
if (!file.mkdir()) {
Log.e("Debug", "Make Dir Error");
}
}
// saving the Path
Calendar cal = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String imgPath = saveDir + "/" + sf.format(cal.getTime()) + ".jpg";
// ファイル保存
FileOutputStream fos;
try {
fos = new FileOutputStream(imgPath, true);
//I want to merge the ImageView
fos.write(data); //writing the data
fos.close();
registAndroidDB(imgPath);
} catch (Exception e) {
Log.e("Debug", e.getMessage());
}
fos = null;
mCam.startPreview();
mIsTake = false;
}
};

Save image to custom folder android on onPictureTaken

i need to save an image to a custom folder in my phone.
my code is
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
FileOutputStream outStream = null;
try {
Random generator = new Random();
int n = 0000;
n = generator.nextInt(n);
String fName = "Image" + n + ".jpg";
outStream = new FileOutputStream(String.format(fName));
outStream.write(data);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
camera.startPreview();
}
not working
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
if(bitmap!=null){
File file=new File(Environment.getExternalStorageDirectory()+"/dirr");
if(!file.isDirectory()){
file.mkdir();
}
file=new File(Environment.getExternalStorageDirectory()+"/dirr",System.currentTimeMillis()+".jpg");
try
{
FileOutputStream fileOutputStream=new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
}
catch(IOException e){
e.printStackTrace();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
}
}
Dont forget to add permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
You can find ans from below code
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
Bitmap m_bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
String destinationPath = Environment.getExternalStorageDirectory() + "/" + "Image.jpg";
if (m_bitmap != null || destinationPath != null)
{
FileOutputStream m_out = new FileOutputStream(destinationPath);
m_bitmap.compress(Bitmap.CompressFormat.JPEG, 100, m_out);
}
}
Hope this code helps you
You first have to create the destination folder you want to save the file into. So, in your Android sdk folder, you create the MediaFiles folder. In this folder you can then create your file.
Here's some code you can try.
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
FileOutputStream outStream = null;
try {
Random generator = new Random();
int n = 0000;
n = generator.nextInt(n);
String fName = "Image" + n + ".jpg";
outStream = new FileOutputStream(GetPathForFileName(fName));
outStream.write(data);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
camera.startPreview();
}
private String GetPathForFileName(String fileName)
{
try
{
String savePath = GetSaveFolderFromConfiguration();
File file = new File(savePath + "/" + fileName);
return savePath + "/" + fileName;
}
catch (Exception ex)
{
ExceptionForm.ShowException(ex);
}
return null;
}
public static String GetSaveFolderFromConfiguration() throws Exception
{
String path = Environment.getExternalStorageDirectory().toString() + "/MediaFiles";
File f = new File(path);
if (f.exists())
return path;
else
f.mkdir();
return path;
}

Call Bitmap inside onPictureTaken

How can I call Bitmap Inside a onPictureTaken method ?. Image is not storing in a gallery until and unless I restart my phone
Please Help in re-arranging the code.
public static int getOrientation(Context context,Uri photoUri){
Cursor cursor = context.getContentResolver().query(photoUri,new String[] {MediaStore.Images.ImageColumns.ORIENTATION},null,null,null);
if(cursor.getCount()!=1){
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
getCorrectlyOrientatedImage() is never used. Please help me in where can I call this function.
public static Bitmap getCorrectlyOrientatedImage(Context context, Uri photoUri)throws IOException{
InputStream is=context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is,null,dbo);
is.close();
int rotatedWidth,rotatedHeight;
int orientation = getOrientation(context,photoUri);
if(orientation == 90 || orientation ==270){
rotatedWidth=dbo.outHeight;
rotatedHeight=dbo.outWidth;
}else{
rotatedWidth=dbo.outWidth;
rotatedHeight=dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if(rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION ){
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio,heightRatio);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
}else{
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
if(orientation > 0){
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap,0,0,srcBitmap.getWidth(),srcBitmap.getHeight(),matrix,true);
}
return srcBitmap;
}
private PictureCallback mPicture = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
Log.d("onPictureTaken", "File is assigned to pictureFile");
if (pictureFile == null) {
Log.d(DEBUG_TAG, " Error creating a media file, check storage permissions:");
return;
}
try {
Bitmap bitmap=getCorrectlyOrientatedImage()
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "SELFie");
String path = mediaStorageDir.getPath() + File.separator + "IMG_Some_name.jpg";
SCamera.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));
} catch (FileNotFoundException e) {
Log.d("DG_DEBUG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
}
}
};
Image is not storing in a SDcard Untill I reboot my phone and also image which is stored is stored in a wrong direction. If photo is taken in portrait , image is stored in landscape . How can store the image in correct orientation.
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"SELFie");
if(!mediaStorageDir.exists()){
if(!mediaStorageDir.mkdir()){
Log.d(DEBUG_TAG,"Filed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
I know this question is a little old, but just in case someone faces the same issue, the solution is to save the image in a background thread as shown in this github link.
private PictureCallback mPicture = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SaveImageTask().execute(data);
}
};
private class SaveImageTask extends AsyncTask<byte[], Void, Void> {
#Override
protected Void doInBackground(byte[]... data) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
Log.d("onPictureTaken", "File is assigned to pictureFile");
if (pictureFile == null) {
Log.d(DEBUG_TAG, " Error creating a media file, check storage permissions:");
return null;
}
try {
Bitmap bitmap=getCorrectlyOrientatedImage()
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "SELFie");
String path = mediaStorageDir.getPath() + File.separator + "IMG_Some_name.jpg";
SCamera.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));
} catch (FileNotFoundException e) {
Log.d("DG_DEBUG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
}
}
}

Save cameraPreview with overlay image

I'm using Google's CameraPreview sample demo. Here, I have the cameraPreview, and an overlayed image over cameraPreview.
When I take the photo, only the cameraPreview is saved, but I need the overlay image to be saved too over the cameraPreview.
This is the way I save cameraPreview's photo, but I need to know what would be the best way for overlaying booth images and save them into one.
public void onPictureTaken(byte[] data, Camera camera) {
String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/miFoto.jpg";
try {
FileOutputStream fos = new FileOutputStream(photoPath);
fos.write(data);
fos.close();
} catch (IOException e) {
Toast.makeText(this, "Pic not saved", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "Pic saved in: " + photoPath, Toast.LENGTH_SHORT).show();
camera.startPreview();
}
I finally made it this way:
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap cameraScaledBitmap = Bitmap.createScaledBitmap(cameraBitmap, 1280, 720, true);
int wid = cameraScaledBitmap.getWidth();
int hgt = cameraScaledBitmap.getHeight();
Bitmap newImage = Bitmap.createBitmap(wid, hgt, Bitmap.Config.ARGB_8888);
Bitmap overlayScaledBitmap = Bitmap.createScaledBitmap(overlayBitmap, wid, hgt, true);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(cameraScaledBitmap , 0, 0, null);
canvas.drawBitmap(overlayScaledBitmap , 0, 0, null);
File storagePath = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
storagePath.mkdirs();
String finalName = Long.toString(System.currentTimeMillis());
File myImage = new File(storagePath, finalName + ".jpg");
String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath() +"/" + finalName + ".jpg";
try {
FileOutputStream fos = new FileOutputStream(myImage);
newImage.compress(Bitmap.CompressFormat.JPEG, 80, fos);
fos.close();
} catch (IOException e) {
Toast.makeText(this, "Pic not saved", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "Pic saved in: " + photoPath, Toast.LENGTH_SHORT).show();
camera.startPreview();
newImage.recycle();
newImage = null;
cameraBitmap.recycle();
cameraBitmap = null;
}

Resizing photo before save or before upload to server

I have this piece of code:
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
Toast.makeText(context, "Dir not created. (ERR#GRA1)", Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("dd_MM_yyyy_HH_mm_ss", Locale.US);
String date = dateFormat.format(new Date());
photoFile = acao + android_id + "_" + date + "_" + coordenadas + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(context, "Saved.", Toast.LENGTH_SHORT).show();
Login.totalTiradas++;
} catch (Exception error) {
Toast.makeText(context, "Not saved. (ERR#GRA2)", Toast.LENGTH_LONG).show();
}
camera2.startPreview();
aviso.setVisibility(View.INVISIBLE);
String stringUrl = "111.222.333.444";
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new conectaFTP().execute(stringUrl);
} else {
Toast.makeText(context, "Fail. Image not sent. (ERR#CON1)", Toast.LENGTH_LONG).show();
}
}
It save the photo to SD card, calls an AsyncTask and uploads the picture. All works fine.
I need to resize the picture. Before saving or before uploading, anyone is good for me.
I couldnt make inSampleSize or Camera.setParameters to work properly (my bad, for sure), or if it's the better way to do this.
First create a Bitmap from byte[]
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
then scale it using Bitmap.createScaledBitmap()
bmp=Bitmap.createScaledBitmap(bmp, width, height, true); // true for if bilinear filter is enabled
Solved by using setParameters:
Camera.Parameters parametro = camera.getParameters();
parametro.setFlashMode("on");
List<Size> sizes = parametro.getSupportedPictureSizes();
for (int i = 0; i < sizes.size(); i++) {
largura = sizes.get(i).width;
altura = sizes.get(i).height;
if (largura >= maxLargura) { break; }
}
parametro.setPictureSize(largura, altura);
camera.setParameters(parametro);

Categories

Resources