saving pictures in portrait orientation - android

I am working on app that use camera preview to take pictures and displaying them in grid view in other activity. But when I take a portrait picture it is saved in my galaxy S4 SD Card in landscape and also display it in grid view in landscape!
Image 1
Image 2
Gridview Activity:
public class GridViewActivity extends Activity {
private ImageAdapter imageAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_view);
GridView gridview = (GridView) findViewById(R.id.gridview);
imageAdapter = new ImageAdapter(this);
gridview.setAdapter(imageAdapter);
String ExternalStorageDirectoryPath = Environment
.getExternalStorageDirectory()
.getAbsolutePath();
String targetPath = ExternalStorageDirectoryPath + "/JCG Camera";
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
for (File file : files){
imageAdapter.add(file.getAbsolutePath());
}
}
in ImageAdapter:
void add(String path){
this.path = path;
imageList.add(path);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(320, 320));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(imageList.get(position), 320, 320);
imageView.setImageBitmap(bm);
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
in camera activity:
private PictureCallback getPictureCallback() {
PictureCallback picture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//make a new picture file
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
//write the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG);
toast.show();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
//refresh camera to continue preview
mPreview.refreshCamera(mCamera);
}
};
return picture;
}
private static File getOutputMediaFile() {
//make a new file directory inside the "sdcard" folder
File mediaStorageDir = new File("/sdcard/", "JCG Camera");
//if this "JCGCamera folder does not exist
if (!mediaStorageDir.exists()) {
//if you cannot make this folder return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
//take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
//and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
I read about EXIF and exifinerface, but I do not know how to use it in my code!

ExiftInterface is a good approach I think. They only thing is that you must have a mechanism that tells you which way your image needs to be rotated (eg. clockwise, counterclockwise). This is what I am using to rotate image.
try {
//You must replace _filePaths.get(position) with the desired object
//You are trying to extract the rotation info. In your case is your data
//But I think you have to save your image first, before you can rotate it.
ExifInterface exif = new ExifInterface(_filePaths.get(position));
//Here you extract the image's rotation info.
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL );
//Here you can convert it to degrees. Using helper method.
int roationInDegrees = exifToDegress(rotation);
Matrix matrix = new Matrix();
//This is where you check if the rotation of the image is not what you want. 0f indicates a portait Image.
if(rotation != 0f){
//Here you specify which way you want to rotate your bitmap according
//To the result of helper method.
matrix.preRotate(roationInDegrees);
image = Bitmap.createBitmap(image,0, 0, imageWidth, imageWidth, matrix, true);
}
} catch (IOException e1) {
e1.printStackTrace();
Log.d("activity#fail", e1.getMessage());
}
private int exifToDegress(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;
}
Make sure you put code inside Try and catch in case the image your are attempting to rotate does not contain any "Orientation" information. Try adding this code right before you write the "data" with your fileoutputstream object.
Good Luck.

Related

captured image quality is low in gridview

I am creating an android app in which the user can click the images which would be shown in grid view once the image is captured this part works fine but the quality of the image is very low and even if i take the image from the high resolution camera it shows the width and height of the image as 160 and 200 px respectively.
I would like to know is there any way to capture the image in original size than compress the image what we do in whatsapp. since i am a newbie to android i don't know what i have to do.
public class CamAct extends Activity implements OnClickListener {
Button captureBtn = null;
final int CAMERA_CAPTURE = 1;
private Uri picUri;
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private GridView grid;
private List<String> listOfImagesPath;
public static final String GridViewDemo_ImagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/GridViewDemo/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camlayout);
captureBtn = (Button)findViewById(R.id.capture_btn1);
captureBtn.setOnClickListener(this);
grid = ( GridView) findViewById(R.id.gridviewimg);
listOfImagesPath = null;
listOfImagesPath = RetriveCapturedImagePath();
if(listOfImagesPath!=null){
grid.setAdapter(new ImageListAdapter(this,listOfImagesPath));
}
}
#Override
public void onClick(View arg0) {
if (arg0.getId() == R.id.capture_btn1) {
try {
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(captureIntent, CAMERA_CAPTURE);
} catch(ActivityNotFoundException anfe){
String errorMessage = "Whoops - your device doesn't support capturing images!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == CAMERA_CAPTURE){
Bundle extras = data.getExtras();
Bitmap thePic = extras.getParcelable("data");
String imgcurTime = dateFormat.format(new Date());
File imageDirectory = new File(GridViewDemo_ImagePath);
imageDirectory.mkdirs();
String _path = GridViewDemo_ImagePath + imgcurTime+".jpg";
try {
FileOutputStream out = new FileOutputStream(_path);
thePic.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
} catch (FileNotFoundException e) {
e.getMessage();
} catch (IOException e) {
e.printStackTrace();
}
listOfImagesPath = null;
listOfImagesPath = RetriveCapturedImagePath();
if(listOfImagesPath!=null){
grid.setAdapter(new ImageListAdapter(this,listOfImagesPath));
}
}
}
}
private List<String> RetriveCapturedImagePath() {
List<String> tFileList = new ArrayList<String>();
File f = new File(GridViewDemo_ImagePath);
if (f.exists()) {
File[] files=f.listFiles();
Arrays.sort(files);
for(int i=0; i<files.length; i++){
File file = files[i];
if(file.isDirectory())
continue;
tFileList.add(file.getPath());
}
}
return tFileList;
}
ImageAdapter:
public class ImageListAdapter extends BaseAdapter
{
private Context context;
private List<String> imgPic;
public ImageListAdapter(Context c, List<String> thePic)
{
context = c;
imgPic = thePic;
}
public int getCount() {
if(imgPic != null)
return imgPic.size();
else
return 0;
}
//---returns the ID of an item---
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.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
bfOptions.inTempStorage=new byte[16 * 1024];
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
FileInputStream fs = null;
Bitmap bm;
try {
fs = new FileInputStream(new File(imgPic.get(position).toString()));
if(fs!=null) {
bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
imageView.setImageBitmap(bm);
imageView.setId(position);
imageView.setLayoutParams(new GridView.LayoutParams(200, 160));
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return imageView;
}
}
Try this:
captureBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(subname.getText().toString().isEmpty()){
Snackbar.make(view, "Select Subject", Snackbar.LENGTH_LONG).show();
}else {
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
ImagefileUri = Uri.fromFile(getFile());
intent.putExtra(MediaStore.EXTRA_OUTPUT, ImagefileUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == CAMERA_PIC_REQUEST){
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int dw = size.x;
int dh = size.y;
// Load up the image's dimensions not the image itself
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(ImagefileUri.getPath(),
bmpFactoryOptions);
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) dh);
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) dw);
Log.v("HEIGHTRATIO", "" + heightRatio);
Log.v("WIDTHRATIO", "" + widthRatio);
if (heightRatio > 1 && widthRatio > 1) {
if (heightRatio > widthRatio) {
// Height ratio is larger, scale according to it
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
// Width ratio is larger, scale according to it
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
// Decode it for real
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(ImagefileUri.getPath(),
bmpFactoryOptions);
InitilizeGridLayout();
// loading all image paths from SD card
imagePaths = utils.getFilePaths();
// Gridview adapter
adapter = new GridViewImageAdapter(Cam.this, imagePaths,
columnWidth);
// setting grid view adapter
gridView.setAdapter(adapter);
}
}else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT).show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
It will capture the image as per the camera width and height so you will get the image in good quality as well as the image adapter you are using has an temp storage which can store only 5 or 6 images of high quality so change the grid view .To know more about displaying images from sdcard to gridview use the following link: Loading images from sdcard and display it in gridview
Hope this code helps you:)

how to create and save a screenshot from a surfaceview?

I have an app that I want to be able to capture a screenshot
Here is my code :
public class Screenshot {
private final View view;
/** Create snapshots based on the view and its children. */
public Screenshot(View root) {
this.view = root;
}
/** Create snapshot handler that captures the root of the whole activity. */
public Screenshot(Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
this.view = contentView.getRootView();
}
/** Take a snapshot of the view. */
public Bitmap snap() {
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
}
but the contents of the surfaceView is saved as black.!!!
Please help me, Thanks...
I hope you have used this solution which was posted here Get screenshot of surfaceView in Android
this thing is explained here Take Screenshot of SurfaceView
The SurfaceView's surface is independent of the surface on which View elements are drawn. So capturing the View contents won't include the SurfaceView.........
I hope this Taking screenshot programmatically doesnt capture the contents of surfaceVIew code can help you out more
public class Cam_View extends Activity implements SurfaceHolder.Callback {
protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
private SurfaceView SurView;
private SurfaceHolder camHolder;
private boolean previewRunning;
final Context context = this;
public static Camera camera = null;
private RelativeLayout CamView;
private Bitmap inputBMP = null, bmp, bmp1;
private ImageView mImage;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
CamView = (RelativeLayout) findViewById(R.id.camview);//RELATIVELAYOUT OR
//ANY LAYOUT OF YOUR XML
SurView = (SurfaceView)findViewById(R.id.sview);//SURFACEVIEW FOR THE PREVIEW
//OF THE CAMERA FEED
camHolder = SurView.getHolder(); //NEEDED FOR THE PREVIEW
camHolder.addCallback(this); //NEEDED FOR THE PREVIEW
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//NEEDED FOR THE PREVIEW
camera_image = (ImageView) findViewById(R.id.camera_image);//NEEDED FOR THE PREVIEW
Button btn = (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE
btn.setOnClickListener(new OnClickListener() { //THE BUTTON CODE
public void onClick(View v) {
camera.takePicture(null, null, mPicture);//TAKING THE PICTURE
//THE mPicture IS CALLED
//WHICH IS THE LAST METHOD(SEE BELOW)
}
});
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
int height) {
if(previewRunning) {
camera.stopPreview();
}
Camera.Parameters camParams = camera.getParameters();
Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
camParams.setPreviewSize(size.width, size.height);
camera.setParameters(camParams);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning=true;
} catch(IOException e) {
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
try {
camera=Camera.open();
} catch(Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) { //NEEDED FOR THE PREVIEW
camera.stopPreview();
camera.release();
camera=null;
}
public void TakeScreenshot(){ //THIS METHOD TAKES A SCREENSHOT AND SAVES IT AS .jpg
Random num = new Random();
int nu=num.nextInt(1000); //PRODUCING A RANDOM NUMBER FOR FILE NAME
CamView.setDrawingCacheEnabled(true); //CamView OR THE NAME OF YOUR LAYOUR
CamView.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="Ghost"+picId+".jpeg";
File dir_image = new File(Environment.getExternalStorageDirectory()+//<---
File.separator+"Ultimate Entity Detector"); //<---
dir_image.mkdirs(); //<---
//^IN THESE 3 LINES YOU SET THE FOLDER PATH/NAME . HERE I CHOOSE TO SAVE
//THE FILE IN THE SD CARD IN THE FOLDER "Ultimate Entity Detector"
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
Toast.makeText(getApplicationContext(),
"The file is saved at :SD/Ultimate Entity Detector",Toast.LENGTH_LONG).show();
bmp1 = null;
camera_image.setImageBitmap(bmp1); //RESETING THE PREVIEW
camera.startPreview(); //RESETING THE PREVIEW
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private PictureCallback mPicture = new PictureCallback() { //THIS METHOD AND THE METHOD BELOW
//CONVERT THE CAPTURED IMAGE IN A JPG FILE AND SAVE IT
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File dir_image2 = new File(Environment.getExternalStorageDirectory()+
File.separator+"Ultimate Entity Detector");
dir_image2.mkdirs(); //AGAIN CHOOSING FOLDER FOR THE PICTURE(WHICH IS LIKE A SURFACEVIEW
//SCREENSHOT)
File tmpFile = new File(dir_image2,"TempGhost.jpg"); //MAKING A FILE IN THE PATH
//dir_image2(SEE RIGHT ABOVE) AND NAMING IT "TempGhost.jpg" OR ANYTHING ELSE
try { //SAVING
FileOutputStream fos = new FileOutputStream(tmpFile);
fos.write(data);
fos.close();
//grabImage();
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
String path = (Environment.getExternalStorageDirectory()+
File.separator+"Ultimate EntityDetector"+
File.separator+"TempGhost.jpg");//<---
BitmapFactory.Options options = new BitmapFactory.Options();//<---
options.inPreferredConfig = Bitmap.Config.ARGB_8888;//<---
bmp1 = BitmapFactory.decodeFile(path, options);//<--- *********(SEE BELOW)
//THE LINES ABOVE READ THE FILE WE SAVED BEFORE AND CONVERT IT INTO A BitMap
camera_image.setImageBitmap(bmp1); //SETTING THE BitMap AS IMAGE IN AN IMAGEVIEW(SOMETHING
//LIKE A BACKGROUNG FOR THE LAYOUT)
tmpFile.delete();
TakeScreenshot();//CALLING THIS METHOD TO TAKE A SCREENSHOT
//********* THAT LINE MIGHT CAUSE A CRASH ON SOME PHONES (LIKE XPERIA T)<----(SEE HERE)
//IF THAT HAPPENDS USE THE LINE "bmp1 =decodeFile(tmpFile);" WITH THE METHOD BELOW
}
};
public Bitmap decodeFile(File f) { //FUNCTION BY Arshad Parwez
Bitmap b = null;
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int IMAGE_MAX_SIZE = 1000;
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
}
try out this also
public static Bitmap overlay(Bitmap bmp1,Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0,0, null);
canvas.drawBitmap(bmp2, 0, 0, null);
Log.i("bmOverlay.......",""+bmOverlay);
bmp3=bmOverlay;
return bmOverlay;
}
private void getScreen() {
Toast.makeText(BookType1.this, "saved", Toast.LENGTH_SHORT).show();
File myDir=new File("/sdcard/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".png";
File file = new File (myDir, fname);
try
{
FileOutputStream ostream = new FileOutputStream(file);
bmp3.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
and you can also go through these references which gives you more idea
How to capture screenshot of surfaceview with background
Taking screen shot of a SurfaceView in android
How to take a screenshot of Android's Surface View?
How to programmatically take a screenshot in Android?

ANDROID HUAWEI device -> cannot get photo URI

im taking photo by using this method:
public void takePhoto () {
try {
Log.i(GlobalApplication.APP_LOG_NAMESPACE, "Trying to take photo");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
} catch (Exception e) {
Log.e(GlobalApplication.APP_LOG_NAMESPACE, "takePhoto method cannot be processed", e);
e.printStackTrace();
}
}
On some devices i got always in onActivity result in image URI null (especially on Huawei devices).
I tried to find any working solution, but without luck.
Could please somebody tell me, how to solve this issue?
Here is onActivityResultMethod:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
Log.i(GlobalApplication.APP_LOG_NAMESPACE, "Trying to process image");
GlobalApplication globalAppClass = ((GlobalApplication) getApplicationContext());
AppHelper helper = new AppHelper();
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
Uri imageUri = data.getData();
if(imageUri == null) {
Log.i(GlobalApplication.APP_LOG_NAMESPACE, "Image URI is null");
}
Bitmap bitmap;
Bitmap resizedBitmap;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "DAMAGE_" + globalAppClass.getEanCode() + "_" + timeStamp + ".jpg";
String dirname = "smartt/"+globalAppClass.getEanCode();
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
resizedBitmap = helper.getResizedBitmap(bitmap, 768, 1024);
helper.createDirectoryAndSaveImage(resizedBitmap, imageFileName, dirname);
// place thumbnail into image view
//mImageView.setImageBitmap(imageBitmap);
TextView photoCountTv = (TextView)findViewById(R.id.damageReportTakenPhotosCountTv);
photoCountTv.setText(R.string.foto_attached);
photoCountTv.setTextColor(getResources().getColor(R.color.green));
TextView dataPassingTv = (TextView)findViewById(R.id.damageReportPassingTitle);
dataPassingTv.setText(R.string.data_passing);
dataPassingTv.setTextColor(getResources().getColor(R.color.green));
} catch (FileNotFoundException e) {
Log.e(GlobalApplication.APP_LOG_NAMESPACE, "onActivityResult method cannot be processed, file not found", e);
e.printStackTrace();
} catch (IOException e) {
Log.e(GlobalApplication.APP_LOG_NAMESPACE, "onActivityResult method cannot be processed, IOE Exception", e);
e.printStackTrace();
} catch (Exception e) {
Log.e(GlobalApplication.APP_LOG_NAMESPACE, "onActivityResult method cannot be processed, Exception", e);
e.printStackTrace();
}
}
}
Thanks for any advice
i know this question is older, but i think many people have a problem with that. As #CommonsWare stated out you have to provide your own URI like this:
photoFile = getOutputMediaFile();
// Continue only if the File was successfully created
if (photoFile != null) {
String fileName = photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
with a file like this:
public File getOutputMediaFile() {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Shaufel");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
// base.saveValidationError("MyCameraApp: failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp
+ ".jpg");
return mediaFile;
}
just safe in your application the fileName (perhaps also onSaveInstanceState())
in onActivityResult i load the bitmap like this
public Bitmap decodeSampledBitmapFromResource(Resources res, File file, int reqWidth,
int reqHeight) throws IOException {
FileInputStream ino = new FileInputStream(new File(fileName));
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(ino.getFD(), null, options);
ino.close();
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(fileName, options);
}
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
this.reqHeight = reqHeight;
this.reqWidth = reqWidth;
// Raw height and width of image
this.height = options.outHeight;
this.width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power
// of 2 and keeps both
// height and width larger than the requested height and
// width.
while ((halfHeight / inSampleSize) > reqHeight
|| (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}

Android bitmap redraw

In my app I take picture from camera and preview it. My app takes picture in landscape mode so that I changed it to portrait mode using exifInterface but I get stretched image.
How can I redraw my Image with out stretched image from the bitmap. if I take picture in landscape mode, it looks good.
this is my code for camera part:
public class TakePic extends Fragment {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater.inflate(R.layout.add_spot_2, container, false);
....
upload.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
String path = Environment.getExternalStorageDirectory()
+ "/pic";
File photopath = new File(path);
if (!photopath.exists()) {
photopath.mkdir();
}
imagePath = new File(photopath, "pic"
+ System.currentTimeMillis() + ".png");
DataPassing.imagePath = imagePath;
if(imageUri==null){
Log.e("Image uri is null", "Image uri is null 1");
}
else{
Log.e("Image uri is NOT null", "Image uri is NOT null 1");
}
Log.e("file path ", imagePath.getAbsolutePath());
imageUri = Uri.fromFile(imagePath);
DataPassing.imageUri = imageUri;
if(imageUri==null){
Log.e("Image uri is null ", "Image uri is null 2");
}
else{
Log.e("Image uri is NOT null", "Image uri is NOT null 2");
}
Log.e("uri file path ", imageUri.getPath());
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imagePath));
startActivityForResult(intent, 100);
}
});
........
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#SuppressWarnings({ "deprecation" })
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == Activity.RESULT_OK) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 10;
if (DataPassing.imageUri == null) {
Toast.makeText(getActivity(), "Please retry",
Toast.LENGTH_SHORT).show();
} else {
Bitmap bm = readBitmap(DataPassing.imageUri);
int or = 0;
try {
or = resolveBitmapOrientation(DataPassing.imagePath);
Log.e("int", String.valueOf(or));
} catch (IOException e) {
e.printStackTrace();
}
if(or==1){
image.setBackgroundDrawable(new BitmapDrawable(bm));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] array = stream.toByteArray();
AddNewSpotValues.comm_2_picture_path = array;
DataPassing.addspot2_bm = bm;
}
else{
int w = bm.getWidth();
int h = bm.getHeight();
Log.e("w & h", ""+w + " & " + h);
Matrix mtx = new Matrix();
mtx.postRotate(90);
Bitmap rbm = Bitmap.createBitmap(bm, 0, 0, w, h, mtx, true);
// Bitmap rbm = Bitmap.createBitmap(bm, 0, 0, 200,150, mtx, true);
image.setBackgroundDrawable(new BitmapDrawable(rbm));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rbm.compress(Bitmap.CompressFormat.PNG, 100, stream);
DataPassing.addspot2_bm = rbm;
byte[] array = stream.toByteArray();
AddNewSpotValues.comm_2_picture_path = array;
}
}
}
}
#Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
}
private Bitmap readBitmap(Uri selectedImage) {
try {
File f = new File(selectedImage.getPath());
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 100;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE
&& o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());
return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
}
}
You might need to open your camera in portrait mode instead of manipulating the image itself accepted answer here show you how to do it

ImageView setImageBitmap not working on certain devices

I was practicing around with the Camera API for which I did the following:
a. Setup a directory for the image captured (for startActivityForResult)
b. Setup the Bitmap so that the image could be shown once saved in the app itself.
Here's the code for the following:
Setting up the directory.
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).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;
}
Global variables in the application
// Activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
// directory name to store the captured images
private static final String IMAGE_DIRECTORY_NAME = "my_camera_app";
private Uri fileUri;
// Views
ImageView photo;
Button camera;
Camera implementation logic
// Use camera function
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Successfully captured the image
// display in imageview
previewImage();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
private void previewImage() {
try {
// Bitmap factory
BitmapFactory.Options options = new BitmapFactory.Options();
// Downsizing image as it throws OutOfMemory exception for larger
// images
options.inSampleSize = 3;
final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
options);
photo.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
The problem I am having is that ... for some of the devices that I tested the app, the app shows a blank preview of the image shot while in others the app works completely well.
Why am I getting a blank feedback ? and in some of the cases, when an image is saved, the user is not directed to my app, instead the user is stuck in the camera app.
Please do help.
I had the same problem and solved it by changing the rendering of the view to software
ImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
At least for Kitkat 4.4.2 on a Galaxy S4, with a relative layout, I had to call invalidate() on the ImageView that i just setImageBitmap on. If i didn't, i got the blank screen. After adding the invalidate() after setImageBitmap(), then I got the image.
try loading bitmap efficiently:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
//BitmapFactory.Options optionss = new BitmapFactory.Options();
//optionss.inPreferredConfig = Bitmap.Config.RGB_565;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeFile(path,options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;}
Actually it is setting but it doesnt appear for some reason.
profileImageView.post(new Runnable() {
#Override
public void run() {
profileImageView.setImageBitmap(bm);
}
});
This works for me.
One way I got around this problem was when setting the FileUri, I stored the Uri using SharedPreferences. So in my code:
public void takePhoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = FileHelper.getOutputMediaFileUri();
// Store uri to SharedPreferences
pref.setImageUri(fileUri.toString());
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, TAKE_PICTURE);
}
In my onActivityResult callback:
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {
// If user is taking photo then only call the SharedPreferences
// If user is selecting photo from gallery, we can use the Intent data
fileUri = Uri.parse(pref.getImageUri());
if (fileUri.getPath().toString().length() < 1) {
Toast.makeText(getApplicationContext(),
"Sorry something went wrong ... Please try again",
Toast.LENGTH_LONG).show();
} else {
String path = fileUri.getPath().toString();
db_img_path = path;
imageholder.setVisibility(View.VISIBLE);
Bitmap bitmap = PathtoImage.previewImage(path);
imagepreview.setImageBitmap(bitmap);
}
}
Bonus :)
In my previewImage method, I have made adjustments for orientation, the code looks like this :
public static Bitmap previewImage(String path) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
final Bitmap bitmap = BitmapFactory.decodeFile(path, options);
// Providing adjustment so that the image is shown in the correct orientation
Matrix adjustment = adjustOrientation(path);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), adjustment, true);
return resizedBitmap;
}
In this method I call another method adjustOrientation which gives me the Matrix fix to the image.
// Adjustment for orientation of images
public static Matrix adjustOrientation(String path) {
Matrix matrix = new Matrix();
try {
ExifInterface exifReader = new ExifInterface(path);
int orientation = exifReader.getAttributeInt(
ExifInterface.TAG_ORIENTATION, -1);
if (orientation == ExifInterface.ORIENTATION_NORMAL) {
// do nothing
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
matrix.postRotate(90);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
matrix.postRotate(180);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
matrix.postRotate(270);
}
} catch (IOException e) {
e.printStackTrace();
}
return matrix;
}
This is my implementation for the issue, if anyone has a better implementation to this, please do post :)
In my case, it's fixed by adding android:layerType="software" in XML.
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layerType="software"
android:src="#drawable/placeholder"/>
Hopefully this will help you too!

Categories

Resources