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);
}
});
}
Related
I want to show the image in Fresco SimpleDraweeView and image is coming from the API and with image width and height so i want to set the image with and height dynamically and also i want to show svg image.
You can pass a ControllerListener when the image is requested.
The onFinalImageSet method contains ImageInfo, which has the image dimensions:
ControllerListener controllerListener =
new BaseControllerListener<ImageInfo>() {
#Override
public void onFinalImageSet(
String id, #Nullable ImageInfo imageInfo, #Nullable Animatable anim) {
if (imageInfo != null) {
int w = imageInfo.getWidth();
int h = imageInfo.getHeight();
// Use these image dimensions to do whatever you want
}
}
};
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 am using Subsampling scale imageview to display a large image (approximately 3000x3000).
I am aslo using picasso decoder to download image from the internet. The problem is, that when I try to get image from cache, it does not work because picasso can not download it. The decoder is from the official page.
I had an idea to download the image and save it to file beforehand and the just show it. The problem is that then I get som skia exception and other stuff, basically, this doesn't seem to be the correct way.
Any ideas ?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.full_image, container, false);
Glide.with(getActivity()).load("http://t0.geograph.org.uk/stamp.php?id=" + mParam1 + "&font=Helvetica&style=&weight=&gravity=South&pointsize=").asBitmap().into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
SubsamplingScaleImageView hillImageView = (SubsamplingScaleImageView) view.findViewById(R.id.hill_image);
hillImageView.setMinimumDpi(80);
hillImageView.setImage(ImageSource.bitmap(resource));
}
});
return view;
}
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) {
}
});
I am using the Android-Universal-Image-Loader library to loading/caching remote images, and have been digging through the source for quite a while trying to find a way to retrieve the original image size (width and height) for my ImageLoadingListener.
The sample code below is just give you an idea of what I'm trying to do.
protected class ViaImageLoadingListener implements ImageLoadingListener {
final SelectableImageView selectableImageView ;
protected ViaImageLoadingListener(SelectableImageView selectableImageView) {
this.selectableImageView = selectableImageView;
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
selectableImageView.setImageBitmap(loadedImage);
// loadedImage.getWeight() will not return the original
// dimensions of the image if it has been scaled down
selectableImageView.setOriginalImageSize(width, height);
selectableImageView.invalidate();
}
I have tried extending the ImageDecoder class and the ImageLoader class to find a round-about way to linking the decoder (from which I can get the original image size in the #prepareDecodingOptions method) to my custom ImageLoadingListener. But the configuration object is private and the fields (including the decoder) are inaccessible from subclasses (and feels like an overly hacky way of solving the problem anyways).
Have I overlooked a simple "built-in" way of getting the original image size without losing the benefit of the UIL's scaling/memory management?
There is no way to pass original image size from ImageDecoder to listener through params.
I think the solution for you is following.
Extend BaseImageDecoder and create map in it for keeping image sizes:
Map<String, ImageSize> urlToSizeMap = new ConcurrentHashMap<String, ImageSize>();
Then override defineImageSizeAndRotation(...):
protected ImageFileInfo defineImageSizeAndRotation(InputStream imageStream, String imageUri) throws IOException {
ImageFileInfo info = super.defineImageSizeAndRotation(imageStream, imageUri);
urlToSizeMap.put(imageUri, info.imageSize); // Remember original image size for image URI
return info;
}
Note: info.imageSize won't compile because imageSize isn't visible. I'll fix it in next version (1.8.5) but you can use reflection for now.
Set this decoder into configuration and keep reference to this decoder anywhere (or you can make urlToSizeMap static to access from listener).
Then in your listener:
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
selectableImageView.setImageBitmap(loadedImage);
ImageSize imageSize = decoder.urlToSizeMap.get(imageUri);
selectableImageView.setOriginalImageSize(imageSize.getWidth(), imageSize.getHeight());
selectableImageView.invalidate();
}
It seems that you do not have to implement own ImageLoadingListener if you want to get original size of loaded image. I use loadImage method and it seems recieved bitmap has origin sizes.
UIL v1.8.6
loader.loadImage(pin_url, option, new SimpleImageLoadingListener() {
#Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
showErrorLayout();
}
#Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
// width - device width
// height - OpenGl maxTextureSize
if (width < loadedImage.getWidth() || height < loadedImage.getHeight()) {
// handle scaling
}
iv.setImageBitmap(loadedImage);
}
});