Compress Image cause Error in Android - java

While clicking photo from smartphone, the image size is too large that it takes minute to upload so I want to reduce image size without affecting too much on its quality. So I got code from this website link. But while adding code in my existing code there are some compiler errors which are fixed.
Below errors are under compressImage(String imageUri) function
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Error is: cannot resolve mrthod 'setScale(float,float,float)'
canvas.setMatrix(scaleMatrix);
Error is: setMatrix (android.graphics.Matrix) in Canvas cannot be applied to (android.opengl.Matrix)
matrix.postRotate(90);
matrix.postRotate(180);
matrix.postRotate(270);
Error is: cannot resolve method 'postRotate(int)'
Code:
public class Camera extends AppCompatActivity implements View.OnClickListener {
public static final String UPLOAD_URL = "http://website.com/ImageUpload/upload.php";
public static final String UPLOAD_KEY = "image";
public static final String UPLOAD_NAME = "name";
public static final String UPLOAD_EMAIL = "email";
public static final String UPLOAD_PHONE= "phone";
public static final String TAG = "MY MESSAGE";
boolean b=false,z;
private int PICK_IMAGE_REQUEST = 1;
String mock;
private Button buttonChoose;
String uploadImage;
private Button buttonUpload,buttonView;
private ImageView imageView;
private Bitmap bitmap,bitmaps;
private Uri filePath;
String path;
String[] max;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
buttonChoose = (Button) findViewById(R.id.buttonChoose);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
buttonView = (Button) findViewById(R.id.buttonViewImage);
buttonUpload.setEnabled(false);
imageView = (ImageView) findViewById(R.id.imageView);
buttonChoose.setOnClickListener(this);
buttonUpload.setOnClickListener(this);
buttonView.setOnClickListener(this);
/* GetSet b= new GetSet();
String maths=b.getCombine();
*/
// System.out.println("Matru "+maths);
Bundle bundle = getIntent().getExtras();
//Extract the data…
String stuff = bundle.getString("combine_data");
// String sss = bundle.getString("combine_data2");
System.out.println("changa " + stuff);
max=stuff.split("~");
for(int i=0;i<max.length;i++)
System.out.println("binku " + max[i]);
}
private void selectImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
}
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(b) {
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
buttonUpload.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
else {
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmaps = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);
imageView.setImageBitmap(bitmaps);
buttonUpload.setEnabled(true);
mock= getStringImage(bitmaps);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public String getStringImage(Bitmap bmp){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
private void uploadImage(){
class UploadImage extends AsyncTask<Bitmap,Void,String>{
ProgressDialog loading;
RequestHandler rh = new RequestHandler();
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(Camera.this, "Uploading Image", "Please wait...",true,true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
imageView.setImageDrawable(null);
buttonUpload.setEnabled(false);
}
#Override
protected String doInBackground(Bitmap... params) {
Bitmap bitmap = params[0];
if(z)
uploadImage = getStringImage(bitmap);
else
uploadImage = mock;
String compress_image=compressImage(uploadImage);
HashMap<String,String> data = new HashMap<>();
data.put(UPLOAD_KEY, compress_image);
data.put(UPLOAD_NAME,max[0]);
data.put(UPLOAD_EMAIL,max[2]);
data.put(UPLOAD_PHONE,max[1]);
String result = rh.sendPostRequest(UPLOAD_URL,data);
return result;
}
}
UploadImage ui = new UploadImage();
ui.execute(bitmap);
}
public String compressImage(String imageUri) {
path = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as 816x612
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float maxRatio = maxWidth / maxHeight;
// width and height values are set maintaining the aspect ratio of the image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
// setting inSampleSize value allows to load a scaled down version of the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(path, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
String filename = getFilename();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filename;
}
private String getRealPathFromURI(String contentURI) {
Uri contentUri = Uri.parse(contentURI);
Cursor cursor = getContentResolver().query(contentUri, null, null, null, null);
if (cursor == null) {
return contentUri.getPath();
} else {
cursor.moveToFirst();
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(index);
}
}
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) {
final int heightRatio = Math.round((float) height/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } final float totalPixels = width * height; final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
public String getFilename() {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
return uriSting;
}
#Override
public void onClick(View v) {
if (v == buttonChoose) {
b=true;
z=true;
showFileChooser();
}
if(v == buttonUpload) {
uploadImage();
}
if(v == buttonView){
b=false;
z=false;
selectImage();
}
}
}

I think if you reduce the bitmap size then may be you can solve this-
public static Bitmap getBitmapFromByteArray(final byte data[], int maxSize) {
final int MAX_SIZE = maxSize;
if (data.length > 0) {
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length, options);
final int fullWidth = options.outWidth;
final int fullHeight = options.outHeight;
int w = 0;
int h = 0;
if (fullWidth > fullHeight) {
w = MAX_SIZE;
h = w * fullHeight / fullWidth;
} else {
h = MAX_SIZE;
w = h * fullWidth / fullHeight;
}
options.inJustDecodeBounds = false;
options.inSampleSize = fullWidth / w;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
options);
return bitmap;
} catch (final Exception e) {
}
}
return null;
}
You will send the current bitmap ByteArray data with size which you want from this bitmap. Then it will return the bitmap by resize. You can try this.

It can be done by two ways i.e degrade quality of jpeg or resizing the image .
Resizing the image
Bitmap mBitmap = Bitmap.createScaledBitmap(bitmap, 480, 300, true);
Reduce quality of jpeg
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outFile);

Related

How to improve the quality of input images and rotate images when taking pictures from the gallery?

I use the code below to get an image from the gallery and capture an image from the camera. But I don't know how my image is degraded. As for taking pictures from the gallery, it is rotated 90 degrees horizontally (I use a samsung phone to take pictures, with my other phone, it's completely normal without rotation)
`
if (resultCode == RESULT_OK) {
//Open Camera
if (requestCode == 2) {
Bitmap imgCam = (Bitmap) data.getExtras().get("data");
int dimension = Math.min(imgCam.getWidth(), imgCam.getHeight());
imgCam = ThumbnailUtils.extractThumbnail(imgCam, dimension, dimension);
cropBitmap = Utils.processBitmap(imgCam, TF_OD_API_INPUT_SIZE);
imgHinh.setImageBitmap(imgCam);
loading = new ProgressDialog(this);
loading.show();
initBox();
imgCam = Bitmap.createScaledBitmap(imgCam, imgSize, imgSize, true);
Bitmap finalImgCam = imgCam;
new CountDownTimer(2000,1000) {
public void onFinish() {
classifyImage(finalImgCam);
loading.dismiss();
}
public void onTick(long millisUntilFinished) {
}
}.start();
//Open Gallery
} else if (requestCode == 3) {
Uri dat = data.getData();
Bitmap imgChoose = null;
try {
imgChoose = MediaStore.Images.Media.getBitmap(this.getContentResolver(), dat);
} catch (IOException e) {
e.printStackTrace();
}
cropBitmap = Utils.processBitmap(imgChoose, TF_OD_API_INPUT_SIZE);
// imgHinh.setImageBitmap(imgChoose);
loading = new ProgressDialog(this);
loading.show();
initBox();
int dimension = Math.min(imgChoose.getWidth(), imgChoose.getHeight());
imgChoose = ThumbnailUtils.extractThumbnail(imgChoose, dimension, dimension);
imgChoose = Bitmap.createScaledBitmap(imgChoose, imgSize, imgSize, true);
imgHinh.setImageBitmap(imgChoose);
Bitmap finalImgChoose = imgChoose;
new CountDownTimer(2000,1000) {
public void onFinish() {
classifyImage(finalImgChoose);
loading.dismiss();
}
public void onTick(long millisUntilFinished) {
}
}.start();
}
}
`
I don't know how to fix that. Thank you for helping me
Try this code it might be helpful...
final int maxSize = 960;
int outWidth;
int outHeight;
int inWidth = myBitmap.getWidth();
int inHeight = myBitmap.getHeight();
if(inWidth > inHeight){
outWidth = maxSize;
outHeight = (inHeight * maxSize) / inWidth;
} else {
outHeight = maxSize;
outWidth = (inWidth * maxSize) / inHeight;
}
Bitmap resizedBitmap = Bitmap.createScaledBitmap(myBitmap, outWidth, outHeight, false);
//Todo Rotate image
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(resizedBitmap, 0, 0, resizedBitmap.getWidth(), resizedBitmap.getHeight(), matrix, true);

Why can't I read files produced by phone main camera, while front camera works

I'm trying to load pictures taken with build-in camera in LG G8 phone.
Code works for front camera, but throws Null Pointer Exception if I switch it to back.
static final int DESIRED_WIDTH = 640;
static final int DESIRED_HIGH = 480;
private Bitmap retrieveBitmap(){
// Get the dimensions of the bitmap
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
//decode only size
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
//returns 0 x 0
int photoW = bitmapOptions.outWidth;
int photoH = bitmapOptions.outHeight;
// Determine how much to scale down the image
float scaleFactor = Math.min( (float) photoW/ (float) DESIRED_WIDTH,
(float) photoH/ (float) DESIRED_HIGH);
// Decode the image file into a Bitmap of given size
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inSampleSize = (int) scaleFactor;
//returns null
Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
return bitmap;
}
Camera app is invoked as in this example using "Save the full-size photo" method. Android reports NullPointerException after first call to BitmapFactory.decodeFile() as if file produced from main camera didn't exist.
E/BitmapFactory: Unable to decode stream: java.lang.NullPointerException
A while ago i too used the guide that you mentioned to be able to use the phone camera to take photos and save them.
The code below activates the phone camera on a button click and allowes both front and back camara to take a photo, then procede to save them. It also displays the photo taken in a ImageView. Hope it helps.
public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
galleryAddPic();
ImageView img = findViewById(R.id.img);
Bitmap bitm = BitmapFactory.decodeFile(mCurrentPhotoPath);
img.setImageBitmap(bitm);
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
public void cameraClick(View v){
dispatchTakePictureIntent();
}
}
Answering my own question:
turns out phone needs some time before large pictures are accessible. Adding a wait loop makes it work:
private Bitmap retrieveBitmap(){
// Get the dimensions of the bitmap
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
//decode only size
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
int i = 0;
while( bitmapOptions.outWidth == 0 && bitmapOptions.outHeight == 0){
//wait for 4 seconds for resource to be available, otherwise fail
try{
wait(1000);
}catch (Exception ex){
ex.printStackTrace();
return null;
}
BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
i++;
//give up trying
if( i == 4) break;
}
//returns 0 x 0
int photoW = bitmapOptions.outWidth;
int photoH = bitmapOptions.outHeight;
// Determine how much to scale down the image
float scaleFactor = Math.min( (float) photoW/ (float) DESIRED_WIDTH,
(float) photoH/ (float) DESIRED_HIGH);
// Decode the image file into a Bitmap of given size
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inSampleSize = (int) scaleFactor;
return BitmapFactory.decodeFile(currentPhotoPath, bitmapOptions);
}

getting a Bitmap from a Uri

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_image);
imageView = (ImageView) findViewById(R.id.imageView);
Intent intent = getIntent();
Uri imageUri = intent.getData();
// Picasso.with(this).load(imageUri).into(imageView);
if(imageUri == null){
Log.d(TAG, "Check");
}
//BitmapFactory.Options options = new BitmapFactory.Options();
// options.inSampleSize = 8;
// bm = MediaStore.Images.Media.getBitmap(getContentResolver(),imageUri);
Bitmap bm = null;
try{
InputStream image;
try{
image = getContentResolver().openInputStream(imageUri);
bm = BitmapFactory.decodeStream(image);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace();
}
//BitmapFactory.Options options = new BitmapFactory.Options();
// bm = BitmapFactory.decodeFile(file.getAbsolutePath(),options);
if ((bm == null)) {
prints("It doesn't work");
}
//Log.d(TAG,"Going to convert image.");
imageView.setImageBitmap(bm);
I've looked at a bunch of StackOverFlow questions, I've tried them all as you can see in the commented code. I'm trying to get a Bitmap that is unchanged when the photo is taken. The pixel position of the Bitmap is crucial for my goal. The image is high quality and maybe a larger file. My Bitmap is always null, I have made sure my Uri isn't. Any ideas?
I think the code below will help you
private void setImage(String path, CircleImageView img) {
options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.showImageOnLoading(R.drawable.user)
.showImageForEmptyUri(R.drawable.user)
.showImageOnFail(R.drawable.user)
.build();
ImageLoader.getInstance().displayImage(path, img, options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
super.onLoadingStarted(imageUri, view);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
super.onLoadingFailed(imageUri, view, failReason);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
super.onLoadingCancelled(imageUri, view);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
}
}, new ImageLoadingProgressListener() {
#Override
public void onProgressUpdate(String s, View view, int i, int i1) {
}
});
}
use universal image loader for SimpleImageLoadingListener()
The file has a too big resolution to make a bitmap out of it. There is not enough memory to construct a bitmap and hence a null is returned.
Try with a very small image file to see.
You can direct get Bitmap from URI if it is from your mobile storage from below code.
public Bitmap getBitmapFromURI(Uri uri){
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
if(cursor!=null){
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
File f_image = new File(cursor.getString(columnIndex));
cursor.close();
BitmapFactory.Options o2 = new BitmapFactory.Options();
return BitmapFactory.decodeFile(f_image.getAbsolutePath(), o2);
}
return null;
}
In case of file is too large to load.. You need to compress image and show. For that you need to use Async Task as well.
I have made one Image compressor task you can use it for large image
public class ConvertBase64Task extends AsyncTask<Void, Bitmap, Bitmap> {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private File file;
private int CompressionRatio = 80; //You can change it by what ever ratio you want. in 0 to 100.
private boolean shouldrotate = true;
private ImageCompressiorListner imageCompressiorListner;
public ConvertBase64Task(File file) {
this.file = file;
}
public void setRotation(boolean isRotate) {
shouldrotate = isRotate;
}
public void setCompressionRatio(int Ratio) {
CompressionRatio = Ratio;
}
public void setImageCompressiorListner(ImageCompressiorListner imageCompressiorListner) {
this.imageCompressiorListner = imageCompressiorListner;
}
#Override
protected void onPreExecute(){
}
#Override
protected Bitmap doInBackground(Void... params) {
try {
//***** Fatching file
//*****Code for Orientation
Matrix matrix = new Matrix();
if (shouldrotate) {
ExifInterface exif1 = new ExifInterface(file.getAbsolutePath());
int orientation = exif1.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
Log.d("EXIF", "Exif: " + orientation);
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
} else {
matrix.postRotate(0);
}
} else {
matrix.postRotate(0);
}
try {
BitmapFactory.Options option = new BitmapFactory.Options();
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), option);
int file_size = Integer.parseInt(String.valueOf(file.length() / 1024));
Log.e("ImageSize", "" + file_size);
int scale = 1;
if (file_size < 512) {
Log.e("image size is good", "image size is less");
} else if (file_size < 1024) {
Log.e("image size is 1 mb", "image size is heavy");
scale = 2;
} else if (file_size < 1536) {
Log.e("image size is 1.5 mb", "image size is heavy");
scale = 2;
} else if (file_size < 2048) {
Log.e("image size is 2 mb", "image size is heavy");
scale = 4;
} else {
Log.e("image size > 2 mb", "image size is heavy");
scale = 4;
}
Log.e("Scale", "Finaly Scaling with " + scale);
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap pickimg = BitmapFactory.decodeFile(file.getAbsolutePath(), o2);
if (pickimg.getWidth() > 1280 || pickimg.getHeight() > 1000) {
int width = pickimg.getWidth();
int height = pickimg.getHeight();
while (width > 1280 || height > 700) {
width = (width * 90) / 100;
height = (height * 90) / 100;
}
pickimg = Bitmap.createScaledBitmap(pickimg, width, height, true);
} else {
pickimg = Bitmap.createBitmap(pickimg, 0, 0, pickimg.getWidth(), pickimg.getHeight(), matrix, true); // rotating bitmap
}
pickimg.compress(Bitmap.CompressFormat.JPEG, CompressionRatio, baos);
return pickimg;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null) {
if(imageCompressiorListner!=null){
imageCompressiorListner.onImageCompressed(result);
}
} else {
if(imageCompressiorListner!=null){
imageCompressiorListner.onError();
}
}
}
public interface ImageCompressiorListner {
void onImageCompressed(Bitmap bitmap);
void onError();
}
}
You can use this as below
ConvertBase64Task task = new ConvertBase64Task(File Object of Image);
task.setImageCompressiorListner(new ConvertBase64Task.ImageCompressiorListner() {
#Override
public void onImageCompressed(Bitmap bitmap) {
}
#Override
public void onError() {
}
});
task.execute();
Hope this will help you out.

Picasso not loading image from file

I really don't know what I am doing wrong.
onPostExecute, the I loaded the ImageView with the file I just created from bitmap:
public class ComicFragment extends Fragment
{
private final static String URL1 = "http://192.168.1.143/jerson/sample_comic.jpg";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_comic, parent, false);
ImageView imageView = (ImageView) view.findViewById(R.id.imageview_comic);
Point point = getScreenSize();
new DownloadImageTask(getActivity(), imageView, point.x, point.y).execute(URL1);
//Uri uri = Uri.parse("http://192.168.1.143/jerson/sample_comic.jpg");
//simpleDraweeView.setImageURI(uri);
return view;
}
private Point getScreenSize()
{
Point point = new Point();
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
display.getSize(point);
return point;
}
private byte [] getBitmapByteArray(Bitmap bitmap)
{
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
return buffer.array();
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// From https://developer.android.com/training/displaying-bitmaps/load-bitmap.html#read-bitmap
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;
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
private Context context;
private int viewWidth;
private int viewHeight;
private ImageView canvas;
public DownloadImageTask(Context context, ImageView view, int viewWidth, int viewHeight)
{
this.context = context;
this.viewWidth = viewWidth;
this.viewHeight = viewHeight;
canvas = view;
}
#Override
protected Bitmap doInBackground(String ... urls)
{
String url = urls[0];
Bitmap comicBitmap = null;
FileOutputStream out = null;
File root = Environment.getExternalStorageDirectory();
File directory = new File(root.getAbsolutePath() + "/DCIM/tmpimg/cached/");
directory.mkdirs();
File file = new File(directory, "tmp.png");
try
{
InputStream forGettingSizeOnly = new BufferedInputStream(new URL(url).openStream());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(forGettingSizeOnly, null, options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
options.inSampleSize = calculateInSampleSize(options, viewWidth, viewHeight);
options.inJustDecodeBounds = false;
// Make this not load another image from network the second time...
InputStream actualImage = new BufferedInputStream(new URL(url).openStream());
Bitmap decodedImage = BitmapFactory.decodeStream(actualImage);
out = new FileOutputStream(file);
comicBitmap = Bitmap.createBitmap(decodedImage, 0, 0, outWidth, 400);
comicBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
Log.i(ComicApplication.TAG, "****File saved at : " + file.getAbsolutePath() + "WxH" + outWidth + " x " + comicBitmap.getHeight());
}
catch(Exception e)
{
e.printStackTrace();
Log.i(ComicApplication.TAG, "ERROR : " + e.getMessage());
}
return comicBitmap;
}
#Override
protected void onPostExecute(Bitmap result)
{
File root = Environment.getExternalStorageDirectory();
File file = new File(root.getAbsolutePath() + "/DCIM/tmpimg/cached/tmp/tmp.png");
Picasso.with(context).load(file).into(canvas);
Log.i(ComicApplication.TAG, "FILE LOADED FROM : " + file.getAbsolutePath());
}
}
}
I am able to see the tmp.png from the phone's image viewer. I am not receiving any exceptions, error, whatsoever from Picasso's end?
Can someone help me out on why is Picasso not loading my image from file?
first, make sure that you are giving Picasso the correct file path,
then you have to add the permission of READ_EXTERNAL_STORAGE in the app Manifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
put this line in the manifest level

Image shown in imageview too small in android despite being wrap_content for height and width

I am working on a project where i click on a button which opens the camera and takes a picture and on coming back to the project it is shown in an imageview.I am saving the image onto a file and when i open the image from my phone's directory it is shown as a big size.How do i make the image shown bigger in the imageview?
The code:
btncamera.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
captureImage();
}
});
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
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode ==getActivity().RESULT_OK) {
// successfully captured the image
// display it in image view
//image_uri=data.getData().toString();
previewCapturedImage();
} else if (resultCode == getActivity().RESULT_CANCELED) {
// user cancelled Image capture
image_path=null;
Toast.makeText(getActivity(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getActivity(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
private void previewCapturedImage() {
try {
// bimatp factory
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),options);
ExifInterface exif = null;
try {
exif = new ExifInterface(fileUri.getPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
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) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, options.outWidth, options.outHeight, matrix, true);
iv_preview.setImageBitmap(rotatedBitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/*
* returning image / video
*/
private 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) {
//change image_path file name required for marina with the name of the file
mediaFile = new File(mediaStorageDir.getPath()+File.separator+user_id+"_"+job_object.job_id+"_"+task_id+".jpg");
// if(mediaFile.exists())
// {
// mediaFile.delete();
// mediaFile = new File(mediaStorageDir.getPath()+File.separator+user_id+"_"+job_object.job_id+"_"+task_id+".jpg");
// }
//IF YOU MAKE CHANGE TO THE FILE NAME PATH ALSO CHANGE IN loadpreviousimage method
image_path=mediaStorageDir.getPath() + File.separator+user_id+"_"+job_object.job_id+"_"+task_id+".jpg";
} else {
return null;
}
return mediaFile;
}
Is it because of this line options.inSampleSize = 4;, that i am getting a small image?
How do i fix the issue?
Yes, inSampleSize if being >1 it will sub sample your image; used to downsize images who are quite large. Source here. And, you could use
android:scaleType="fitXY" in ImageView to fit your image in your ImageView
use this method for decode,
public Bitmap decodeFile(String path) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 70//put size you want;
// 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.decodeFile(path, o2);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
hope this will help you

Categories