I have an app which takes photos of receipts and upload it to a remote server.
I get the full-sized photo of the image from the camera intent correctly.I followed this using the official documentation in Google developer.
I then set my picture like this.
private void setPic() {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
//Bitmap bitmap = null;
//try
//{
//bitmap = MediaStore.Images.Media.getBitmap(getContentResolver() , //Uri.parse(mCurrentPhotoPath));
//}
//catch (Exception e)
//{
//handle exception
//}
imageView.setImageBitmap(bitmap);
new ImageSaver(getApplicationContext()).
setFileName("currentImage.png").
setDirectoryName("Android_Upload").
save(bitmap);
Model.currentImage = "currentImage.png";
}
This works fine when viewed on the device. But after its sent to the server and viewed from there, the image size is too small.
ImageSaver class pretty much saves the image elsewhere and compresses it but with 100 quality in png.I do this, so I can later the image in the database as Blob(again with 100 quality)
How can I decode the image and show the image in the image view but without losing quality (and the size?)
Apparently, you have scaled down your image while decoding.
You may want to remove the following line:
bmOptions.inSampleSize = scaleFactor;
Related
I want to let a image on my phone to show up in the Imageview. But in the ANdroid Studio emulator it is working but not on my own phone.
String imgPath = getIntent().getExtras().getString("imgPath");
System.out.println(imgPath);
if(!imgPath.equals("?"))
{
File img_file = new File(imgPath);
ImageView imgView = findViewById(R.id.show_image_war);
imgView.setImageURI(Uri.fromFile(img_file));
}
The path is /storage/emulated/0/imagesWarranty/img_MyWarranty_ID1.jpg . Both on the image in my phone and the path in my code where I get the image.
It might be issue of resolution. Even I was getting error of resolution while I was displaying image from uri.
I used below code and It worked for me :
Uri imageUri = Uri.parse(imagePath);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(imageUri.getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
if (imageHeight > 4096 || imageWidth > 4096) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(imageUri.toString(), opts);
viewHolder.imgAvatarLogoList3.setImageBitmap(bitmap);
} else {
Picasso.with(context)
.load(new File(imageUri.getPath())) // Uri of the picture
.into(viewHolder.imgAvatarLogoList3);
}
Addition to this answer [https://stackoverflow.com/a/48354307/9255006]
In that rotation bug define the image orientation for the image using ExifInterface.
Here is the code
private void SetOrientation(){
try {
ExifInterface exif=new ExifInterface(photoURI.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_UNDEFINED);
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { orientationInDegrees=90; }
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { orientationInDegrees=180; }
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { orientationInDegrees=270; }
else { orientationInDegrees=0; }
Toast.makeText(this, String.valueOf(orientationInDegrees), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
You can then set this orientation to your image.
This happens when the image has a very high resolution that the system needs some additional milliseconds to display, and since this happens in the UI thread onDraw() of the image view will draw it as an empty.
The easiest way I found for this issue is to use the Picasso library this way:
Picasso.get().load(imgUri).fit().centerCrop()
.into(imageview);
The reason behind those two methods (fit(), centerCrop())
Is that fit make sure that the image fit the bound container and then crop the image which force the system to redraw the image but this time with the convenient resolution (because of fit and crop).
I am trying to simply get an image from a phone's camera. Surprisingly, it returns rotated. I've scoured the internet for fixes and came across many solutions using ExifInterface, but it only works sometimes. It gets the orientation wrong seemingly randomly, as I merely recompile and see different results. I have found some people saying this is a fault of the class itself being bugged.
I found other solutions that require like two additional libraries and more java files to do the job, but that just seems ridiculous (and I am avoiding additional packages). How come images are rotated in the first place (in storage they are perfectly fine), and how hard can it possibly be to fix the issue? Also - rotating the Image View also works (and seems much easier than literally creating a rotated image), but I need to know by how much to rotate the view.
EDIT---- I realized that the image is consistently rotated 270 degrees clockwise from the orientation the image was taken in (inside the intent) if the back camera was used, and 90 degrees if the front camera was used. Thus I only really need a way to find out this orientation.
Intent called here:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = setUpPhotoFile();
mCurrentPhotoPath = photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} catch (IOException ex) {
// Error occurred while creating the File
photoFile = null;
mCurrentPhotoPath = null;
}
// Continue only if the File was successfully created
if (photoFile != null) {
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
} else {
Toast noStorage = Toast.makeText(this, "Cannot access mounted storage.", Toast.LENGTH_SHORT);
noStorage.show();
}
}
}
Bitmap created here:
private void setPic() {
/* Get the size of the ImageView */
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scale = 1;
if (photoH > targetH|| photoW > targetW) {
scale = Math.max(
(int)Math.pow(2, (int) Math.ceil(Math.log(targetW /
(double) photoW)) / Math.log(0.5)),
(int)Math.pow(2, (int) Math.ceil(Math.log(targetH /
(double) photoH)) / Math.log(0.5)));
;
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scale;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
/*-----------How should I rotate bitmap/mImageView to correct orientation?*/
/* Associate the Bitmap to the ImageView */
mImageView.setImageBitmap(bitmap);
mImageView.setVisibility(View.VISIBLE);
}
The best solution I have found is this one:
https://www.samieltamawy.com/how-to-fix-the-camera-intent-rotated-image-in-android/
I post the link because I don't want all the credit.
Sami Eltamawy has written a function that rotate the image if its need to be rotated.
I try the code and is working on my devices that the image got rotated.
I am following this tutorial to take a picture, save, scale and use it in android. However I am getting the Android: open failed: ENOENT (No such file or directory) error when trying to open/retrieve the saved image. After some research I found this post which assumes that this issue comes with files which contain digits in their names, like mine which are given a name with current time stamp. I checked that the images are saved in file directory and I logged to make sure the file name being used to retrieve them matches the original name.
Here is the part of my code that gives the error:
private void setPic(ImageView myImageView) {
// Get the dimensions of the View
int targetW = myImageView.getWidth();
int targetH = myImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
Log.v("IMG Size", "IMG Size= "+String.valueOf(photoW)+" X "+String.valueOf(photoH));
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
myImageView.setImageBitmap(bitmap);
}
And here is what logging shows me:
E/BitmapFactory﹕ Unable to decode stream: java.io.FileNotFoundException: /file:/storage/sdcard0/Pictures/JPEG_20150728_105000_1351557687.jpg: open failed: ENOENT (No such file or directory)
And I am trying to open the image named: JPEG_20150728_105000_1351557687.jpg
I downloaded your code and tried to use the same in my application. Found that the prefix /file: causing the FileNotFoundException.
Replace your method will the following method.
private void setPic(ImageView myImageView) {
// Get the dimensions of the View
int targetW = myImageView.getWidth();
int targetH = myImageView.getHeight();
String path = mCurrentPhotoPath.replace("/file:","");
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
Log.v("IMG Size", "IMG Size= " + String.valueOf(photoW) + " X " + String.valueOf(photoH));
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, bmOptions);
myImageView.setImageBitmap(bitmap);
}
I have a resource image. If I read its dimensions without actually decoding, all is fine (even if asking for RGB565). If I decode into RGB565 color format the Android API provides me with dimensions double too wide and too high.
Is this a bug in Android?
private static Bitmap decodeBitmapAsRGB565( Resources res, int resId ) {
BitmapFactory.Options opt = new BitmapFactory.Options();
int origW, origH;
opt.inJustDecodeBounds= true; // don't decode contents, just get the dimensions
{
// Get original picture's dimensions
//
BitmapFactory.decodeResource( res, resId, opt );
Log.v("", String.format("*** Original: %d x %d", opt.outWidth, opt.outHeight)); // 1532x2048
origW= opt.outWidth;
origH= opt.outHeight;
opt.inPreferredConfig= Bitmap.Config.RGB_565;
BitmapFactory.decodeResource( res, resId, opt );
Log.v("", String.format("*** RGB565: %d x %d", opt.outWidth, opt.outHeight)); // 1532x2048
}
opt.inJustDecodeBounds= false;
opt.inPreferredConfig= Bitmap.Config.RGB_565; // needed for 'EFFECT_REDEYES'
final Bitmap bmp= BitmapFactory.decodeResource( res, resId, opt );
// Check that we got the size of the original
//
int w= bmp.getWidth();
int h= bmp.getHeight();
if ((w!=origW) || (h!=origH)) {
String s; Log.wtf("", s= String.format("Bitmap dimensions screwed: (%d,%d) vs. (%d,%d)", w,h, origW,origH));
throw new RuntimeException(s);
}
return bmp;
}
Resources are scaled accordingly to the device's screen density. If you want to avoid the scaling you can put the resources inside the drawable-nodpi directory.
I am having trouble of displaying the large image into android. I have tried to get this done by this custom- scrollable-image-view .
I have used full View in my class and used the 7165*786 size of image into it. And it is of only 1.11MB of image. I am able to run this code in bluestack and see the image in it but it couldn't be load in real device.
bmLargeImage = BitmapFactory.decodeResource(getResources(),
R.drawable.imagewithout);
bmlotusImage1 = BitmapFactory.decodeResource(getResources(),
R.drawable.lotus);
I am using the same canvas in onDraw methow as below.
canvas.drawBitmap(bmLargeImage, scrollRect, displayRect, paint);
canvas.drawBitmap(bmlotusImage1, 45 - newScrollRectX,
255 - newScrollRectY, paint);
i could not be able to display the bmlargeImage in my real device i can see the lotus image on Device but not the large one.
Should i have to decode or scale the image or anything else to get it display in real device?
i get the solution of not Displaying the image in real Device the problem was the simply.
I have just removed the target sdk a i get the error in webservice. It start showing the image to my real device also and also i get the solution for Displaying the image FIt to screen as below.
private static Bitmap ShrinkBitmap(String backgroundimage, int width,
int height) {
// TODO Auto-generated method stub
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(backgroundimage,
bmpFactoryOptions);
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) height);
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) width);
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(backgroundimage, bmpFactoryOptions);
return bitmap;
}
And i have passed the image width adn height as the parameter in this method.
bmLargeImage = ShrinkBitmap(backgroundimage, 7165, 786);