I am using the Glide image loading library and I'm having issues when it comes to resizing bitmaps.
When using the following code:
Glide.with(getActivity())
.load(images.get(i))
.asBitmap().centerCrop()
.into(new SimpleTarget<Bitmap>(1200, 1200) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
}
});
Every single bitmap gets resized to the specified dimensions. So, if the image is 400x300, it gets upscaled up to 1200 x 1200 which I do not want. How do I make it so that if the image is smaller than the specified dimensions, it won't resize it?
I'm specifying dimensions because I want every image that's bigger than the specified dimensions to be resized taking into account centerCrop; and then if the image is smaller than the specified dimensions, I don't want it to be resized.
I want every image that's bigger than the specified dimensions to be
resized taking into account centerCrop; and then if the image is
smaller than the specified dimensions, I don't want it to be resized.
You can obtain this behaviour with a custom transformation:
public class CustomCenterCrop extends CenterCrop {
public CustomCenterCrop(BitmapPool bitmapPool) {
super(bitmapPool);
}
public CustomCenterCrop(Context context) {
super(context);
}
#Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
if (toTransform.getHeight() > outHeight || toTransform.getWidth() > outWidth) {
return super.transform(pool, toTransform, outWidth, outHeight);
} else {
return toTransform;
}
}
}
and then use it like this:
Glide.with(getActivity())
.load(images.get(i))
.asBitmap()
.transform(new CustomCenterCrop(getActivity()))
.into(new SimpleTarget<Bitmap>(1200, 1200) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
}
});
Related
I am having trouble showing images correctly in my application.
I wish the picture would retain its original proportions. I display
picture in the AppBar,
I am using Picasso to download images, but cannot get the height and width of the downloaded image.
I've tried various solutions from other threads on StackOverflow, but unfortunately none of them work.
Can you help me get the height and width of the downloaded image using Picasso?
You can use bitmap target.
Load image in bitmap, get width and height and then set bitmap image in imageView. Glide library has the same feature.
Picasso.with(this).load(url).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
imageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
So I have a basic question about Glide. Im doing an android test application and just want to transform an image to fit the screen.
This was the old code:
Bitmap background, backgroundresized;
(...)
//load image
background = BitmapFactory.decodeResource(context.getResources(), R.drawable.gamebackground);
}
void onDraw(Canvas canvas) {
if(first_time){
width = canvas.getWidth();
height = canvas.getHeight();
backgroundresized = Bitmap.createScaledBitmap(background, width, height, true);
first_time=false;
}
canvas.drawBitmap(backgroundresized, 0, 0, null);
}
This isn't the best approach to fit a screen, I know, I use this and drawable-xhdpi/xxhdpi/xxxhdpi folders.
But how to use Glide to do this, and hopefully recycle the image if the user comes back to this screen?
Allright, there are different ways to do, but easy way to keep static instance of that class because glide stays as inner class when you try to assign to upper. check following sample code
public class SomeActivity extends Activity {
static Bitmap somebitmap;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int myWidth = 512;
int myHeight = 384;
Glide.with(this)
.asBitmap()
.load("URL")
.into(new SimpleTarget<Bitmap>(myWidth, myHeight) {
#Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
somebitmap = resource;
}
});
}
}
I use Glide to load my image. I need to modify my image with a SimpleTarget callback, however when the image loaded to my list, and I scroll the list shows first always an other image, and than animate the right image after 1 second to the place. Without image modification and SimpleTarget everything works just fine. Here is my code.
#BindingAdapter("imageSrc")
public static void setImage(ImageView imageView, String url) {
Glide.with(imageView.getContext()).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
//the bitmap modified here
imageView.setImageBitmap(bmp);
}
});
}
is there any solution to avoid the flickering?
I'm using Glide to load images on Scale ImageView - it is a custom view with pan and zoom gestures. I should pass Bitmap object to this custom view in order to set picture.
So I can use Glide's .asBitmap() with SimpleTarget:
private SimpleTarget target = new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
scaleImageView.setImage(ImageSource.bitmap(bitmap));
}
};
private void loadImageSimpleTarget() {
Glide
.with(context)
.load(url)
.asBitmap()
.into(target);
}
This code snippet works well, but I will get fullsize Bitmap, which can lead to OutOfMemoryErrors. Also I could specify desired Bitmap size on constructor like this: ...new SimpleTarget<Bitmap>(250, 250)..., but I would have to manually calculate dimensions.
Is there a possibility to pass view (instance of CustomView) to Glide's request, so dimensions will calculated automatically and receive Bitmap object as a result?
Continuing the discussion from the comments, you get 0 for width and height when calling it from onCreateView. However, you can set a listener to be notified when the bounds of the view are actually calculated and then you can get the real width and height by calling getWidth or getHeight:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
// your other stuff
// ...
// set listener
customView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("debug", "width after = " + customView.getHeight());
// pass the width and height now that it is available
target = new SimpleTarget<Bitmap>(customView.getWidth(), customView.getHeight()) {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
scaleImageView.setImage(ImageSource.bitmap(bitmap));
}
};
// remove listener, we don't need to be notified again.
customView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
I have a fully working shared element transition between 2 fragments, lets say A to B, and they both share an ImageView. Everything works out except when I replace the shared ImageView on B. Currently I'm changing it using the following code:
Glide.with(getActivity())
.load(getArguments().getString(Constants.APPVIEW_FEATURE_IMAGE_URL)).asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
if (getView() != null) {
((ImageView) getView().findViewWithTag(Constants.TAG_FGRAPHIC)).setImageBitmap(resource);
}
}
});
I replace the ImageView that I received from A on B with a higher definition one, since this is a header Image that will extend from a listView to a full width header.
The problem is that when returning from B to A, the animation goes wrong because when I press Back, the image changes size right away to it's size on A instead of using the animation scaling down from it's B size to A size. It still moves from the header to the A location correctly, it's just the size problem.
If I don't replace the image, no problem happens and everything goes normal.
Any idea? Thanks.
I am not sure how to do it with Glide, but this is how I did it with Picasso.
Picasso.with(context)
.load(AppController.getInstance().getThumbor().buildImage(url)
.resize(widthPlaceholder, heightPlaceholder)
.fitIn()
.toUrl())
.placeholder(R.color.light_gray)
.centerCrop()
.noFade()
.config(Bitmap.Config.RGB_565)
.into(target);
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable d = new BitmapDrawable(context.getResources(), bitmap);
Picasso.with(context)
.load(AppController.getInstance().getThumbor().buildImage(url)
.resize(width, height)
.fitIn()
.toUrl())
.placeholder(d)
.centerCrop()
.noFade()
.config(Bitmap.Config.RGB_565)
.into(imageView);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Picasso.with(context)
.load(AppController.getInstance().getThumbor().buildImage(url)
.resize(width, height)
.fitIn()
.toUrl())
.placeholder(R.color.light_gray)
.config(Bitmap.Config.RGB_565)
.centerCrop()
.noFade()
.into(imageView);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Picasso.with(context)
.load(AppController.getInstance().getThumbor().buildImage(url)
.resize(width, height)
.fitIn()
.toUrl())
.placeholder(placeHolderDrawable)
.config(Bitmap.Config.RGB_565)
.centerCrop()
.noFade()
.into(imageView);
}
};
I am loading lower resolution picture and I am putting it as placeholder (background image), and than triggering higher res picture loading.