Java Android glide resize image [duplicate] - java

This question already has answers here:
Resize images with Glide in a ImageView Android
(6 answers)
Closed 4 years ago.
I want to resize image use by glide . Now I use a picasso but I want to use a glide
private void resizeImg(Context context, final File file, int targetSize, Handler handler) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getPath(), options);
float ratio = Math.max(options.outWidth, options.outHeight) / (float) targetSize;
//don't scale image that is smaller than targetSize
if (ratio < 1) return;
int dstWidth = (int) (options.outWidth / ratio);
int dstHeight = (int) (options.outHeight / ratio);
PicassoTargetFactory.getInstance().putTarget(file, handler);
Picasso.with(context)
.load(file)
.error(R.drawable.ic_delete)
.resize(dstWidth, dstHeight)
.into(PicassoTargetFactory.getInstance().getTarget(file));
ArrayList<String> paths = new ArrayList<>();
files = new ArrayList<>();
files.add(mCurrentPhotoPath);
for (File f : files) {
paths.add(f.getAbsolutePath());
}
mdb.insertPhotos(paths);
}
How I can do this ? On piccaso sometimes I have a cut image

first, add Glide lib in Gradle. Then, u can use it like this
Glide
.with(context)
.load("your image path")
.override(600, 200) // resizes the image to these dimensions (in pixel). resize does not respect aspect ratio
.into(imageViewResize);

Override must be accessed via RequestOptions in the most recent version of Glide.
Glide
.with(context)
.load(path)
.apply(new RequestOptions().override(600, 200))
.into(imageViewResizeCenterCrop);

You can create RequestOptions class object & pass it on apply() method in Glide.
Use like,
Glide.with(context)
.load(url)
.apply(new RequestOptions().override(Your image size here))
.into(imageView);
More From here

I think you should give your methods a single responsibility. You want a method that resizes an image but yours actually does more. Please separate things
private Bitmap resizeBitmap(Bitmap b, int w, int h) {
// Your code.
return myResizedBitmap;
}
Then it will be easier to help you

private String getImgCachePath(String url) {
FutureTarget<File> futureTarget = Glide.with(getBaseContext()).load(url).downloadOnly(100, 100);
try {
File file = futureTarget.get();
String path = file.getAbsolutePath();
return path;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
100,100 is width and height of image you want to save, change it as per your need. path is the path of cached image of given resolution of image url.

Related

SetImageUri showing no Image

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).

Image from ACTION_IMAGE_CAPTURE Rotated

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.

Getting current image from imageview (android)

I have an ImageView in which I load images from camera and gallery , and I do it using imgview.setimagebitmap(bitmap) ,( and I change the image again and again ) it works fine, but when I try to get the current image back for some processing (applying effect or rotate) it returns me the old image not the current one.
I think the problem is with imgview.setimagebitmap(bitmap).
can I be helped?
I have the following code:
try {
iv_image.buildDrawingCache();
Bitmap source = iv_image.getDrawingCache();
} catch(Exception ex) {
int a;
int b;
a = 11;
b = 12;
}
Can you please try to obtain the batman as follows :
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap()

Decode specific areas of image in Bitmapfactory?

I'm working with GeoTiff/PNG files too large for handling as a whole in my code.
Is there any possibility to decode specific areas (e.g. given by two x,y coordinates) of a file in bitmapfactory? Haven't found anything looking similar at http://developer.android.com/reference/android/graphics/BitmapFactory.html(Android's developer reference).
Thanks!
With kcoppock's hint I've set up the following solution.
Though I'm wondering why rect needs to be initialized by Rect(left, bottom, right, top) instead of Rect(left, top, right, bottom)...
Example call:
Bitmap myBitmap = loadBitmapRegion(context, R.drawable.heightmap,
0.08f, 0.32f, 0.13f, 0.27f);
Function:
public static Bitmap loadBitmapRegion(
Context context, int resourceID,
float regionLeft, float regionTop,
float regionRight, float regionBottom) {
// Get input stream for resource
InputStream is = context.getResources().openRawResource(resourceID);
// Set options
BitmapFactory.Options opt = new BitmapFactory.Options();
//opt.inPreferredConfig = Bitmap.Config.ARGB_8888; //standard
// Create decoder
BitmapRegionDecoder decoder = null;
try {
decoder = BitmapRegionDecoder.newInstance(is, false);
} catch (IOException e) {
e.printStackTrace();
}
// Get resource dimensions
int h = decoder.getHeight();
int w = decoder.getWidth();
// Set region to decode
Rect region = new Rect(
Math.round(regionLeft*w), Math.round(regionBottom*h),
Math.round(regionRight*w), Math.round(regionTop*h));
// Return bitmap
return decoder.decodeRegion(region, opt);
}
You should look into BitmapRegionDecoder. It seems to describe exactly the use case that you are looking for.
I don't know exactly what you mean by "Decode specific areas" but if by decoding you mean, to actually "copy" certain areas of a bitmap, what you can do is make use of canvas in order to get it as shown below:
Bitmap bmpWithArea = Bitmap.createBitmap(widthDesired, heightDesired, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmpWithArea);
Rect area = new Rect(arealeft, areatop, arearight, areabottom);
Rect actualSize = new Rect(0, 0, widthDesired, heightDesired);
canvas.drawBitmap(bitmapWithAreaYouWantToGet, area, actual, paintIfAny);
//And done, starting from this line "bmpWithArea" has the bmp that you wanted, you can assign it to ImageView and use it as regular bmp...
Hope this helps...
Regards!

Bitmap Memory Error Android

I am making an Android game, but when I load my Bitmaps, I get a memory error. I know that this is caused by a very large Bitmap (it's the game background), but I don't know how I could keep from getting a "Bitmap size extends VM Budget" error. I can't rescale the Bitmap to make it smaller because I can't make the background smaller. Any suggestions?
Oh yeah, and here's the code that causes the error:
space = BitmapFactory.decodeResource(context.getResources(),
R.drawable.background);
space = Bitmap.createScaledBitmap(space,
(int) (space.getWidth() * widthRatio),
(int) (space.getHeight() * heightRatio), false);
You're going to have to sample down the image. You can't "scale" it down smaller than the screen obviously, but for small screens etc it doesn't have to be as high resolution as it is for big screens.
Long story short you have to use the inSampleSize option to downsample. It should actually be pretty easy if the image fits the screen:
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Display display = wm.getDefaultDisplay();
final int dimension = Math.max(display.getHeight(), display.getWidth());
final Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
InputStream bitmapStream = /* input stream for bitmap */;
BitmapFactory.decodeStream(bitmapStream, null, opt);
try
{
bitmapStream.close();
}
catch (final IOException e)
{
// ignore
}
final int imageHeight = opt.outHeight;
final int imageWidth = opt.outWidth;
int exactSampleSize = 1;
if (imageHeight > dimension || imageWidth > dimension)
{
if (imageWidth > imageHeight)
{
exactSampleSize = Math.round((float) imageHeight / (float) dimension);
}
else
{
exactSampleSize = Math.round((float) imageWidth / (float) dimension);
}
}
opt.inSampleSize = exactSampleSize; // if you find a nearest power of 2, the sampling will be more efficient... on the other hand math is hard.
opt.inJustDecodeBounds = false;
bitmapStream = /* new input stream for bitmap, make sure not to re-use the stream from above or this won't work */;
final Bitmap img = BitmapFactory.decodeStream(bitmapStream, null, opt);
/* Now go clean up your open streams... : ) */
Hope that helps.
This may help you: http://developer.android.com/training/displaying-bitmaps/index.html
From the Android Developer Website, a tutorial on how to efficiently display bitmaps + other stuff. =]
I don't understand why are you using ImageBitmap? for background. If its necessary , its okay. Otherwise please use Layout and set its background because you are using background image.
This is important. (Check Android docs. They have clearly indicated this issue.)
You can do this in following way
Drawable d = getResources().getDrawable(R.drawable.your_background);
backgroundRelativeLayout.setBackgroundDrawable(d);
In most android devices the Intent size equals 16MB. You MUST Follow these instructions Loading Large Bitmap Efficiently

Categories

Resources