I am trying to get height and width of network image. I am using Glide to display image.
Code I've used in Java is:
Glide.with(getContext().getApplicationContext())
.asBitmap()
.load(path)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap,
Transition<? super Bitmap> transition) {
int w = bitmap.getWidth();
int h = bitmap.getHeight()
mImageView.setImageBitmap(bitmap);
}
});
How can I achieve this in Kotlin?
Glide.with(context.applicationContext)
.asBitmap()
.load(path)
.into(object : SimpleTarget<Bitmap?>() {
override fun onResourceReady(bitmap: Bitmap, transition: Transition<in Bitmap?>?) {
val w = bitmap.width
val h = bitmap.height
mImageView.setImageBitmap(bitmap)
}
})
Related
I'm trying to rotate my image in Glide.
I've created BitmapTransformation as it's said in the documentation.
Problem is that overrided method transform is not called so image is not rotated at all. I'm using Glide 3.7.0
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Uri imageUri = this.imageUri;
Glide.with(getContext())
.load(imageUri)
.transform(new RotateTransformation(getContext(), 90))
.fitCenter()
.into(imageView);
}
public class RotateTransformation extends BitmapTransformation {
private float rotateRotationAngle = 0f;
public RotateTransformation(Context context, float rotateRotationAngle) {
super(context);
this.rotateRotationAngle = rotateRotationAngle;
}
#Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Matrix matrix = new Matrix();
matrix.postRotate(rotateRotationAngle);
return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
}
#Override
public String getId() {
return "rotate" + rotateRotationAngle;
}
}
update
Glide.with(getContext())
.load(imageUri)
.transform(new RotateTransformation(getContext(), 90))
.fitCenter()
.into(imageView);
to
Glide.with(getContext())
.load(imageUri)
.fitCenter()
.transform(new RotateTransformation(getContext(), 90))
.into(imageView);
Why I can't resolve this method while using Glide also I can't resolve .diskstaretegy() :
Glide.with(getActivity())
.load(chalet.profilePhoto)
.asBitmap() <--- cannot resolve this
.diskCacheStrategy(DiskCacheStrategy.ALL) <--- cannot reslove this
.fitCenter()
.placeholder(R.drawable.logo).dontAnimate().into(mImageView);
My gradle :-
compile 'com.github.bumptech.glide:glide:4.0.0'
I found the way to fix it, you must add the asBitmap() right After with() and it will work just like old times.
PS: my Glide Version is 4.7.1
for the asBitmap you need to write it as follows:
Glide.with(getActivity()).asBitmap().load(chalet.profilePhoto).into(mImageView);
// Put asBitmap() right after Glide.with(context) ,,. 4.0+
// And for SubsamplingScaleImageView use SimpleTarget
Glide.with(context)
.asBitmap()
.load(images[position])
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
.into(new SimpleTarget<Bitmap>(width, height) {
#Override
public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
subsampleImageView.setImage(ImageSource.bitmap(bitmap)); //For SubsampleImage
}
});
Call asBitmap() before load()
Glide.with(context)
.asBitmap()
.load(uri)
If you getting an error, follow the steps below.
In Glide library move .asBitmap() before the .load()
---------------------OR-----------------------
Glide.with(context)
.setDefaultRequestOptions(requestOptions)
.asBitmap()
.load(url)
.into(holder.imageView);
https://bumptech.github.io/glide/doc/migrating.html#requestoptions
Glide.with(getActivity()).asBitmap()
.load(headerURl)
.listener(new RequestListener<Bitmap>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object o, Target<Bitmap> target, boolean b) {
// Toast.makeText(cxt,getResources().getString(R.string.unexpected_error_occurred_try_again),Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onResourceReady(Bitmap bitmap, Object o, Target<Bitmap> target, DataSource dataSource, boolean b) {
if (null == header)
return false;
//set image
header.setImageBitmap(bitmap);
//process bitmap
Palette.from(bitmap).generate(
new Palette.PaletteAsyncListener() {
#SuppressWarnings("ResourceType")
#Override
public void onGenerated(Palette palette) {
int vibrantColor = palette
.getVibrantColor(R.color.primary_500);
int vibrantDarkColor = palette
.getDarkVibrantColor(R.color.primary_700);
collapsingToolbarLayout
.setContentScrimColor(vibrantColor);
collapsingToolbarLayout
.setStatusBarScrimColor(vibrantDarkColor);
}
});
return false;
}
}
).submit();
You can set it another way like that
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.ic_placeholder);
requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL)
requestOptions.error(R.drawable.ic_error);
Glide.with(context)
.setDefaultRequestOptions(requestOptions)
.asBitmap()
.load(url).into(holder.imageView);
I am trying to fetch Bitmap of image stored on Sd card using Glide but it is not working for me.
Bitmap bitmapByGlide = Glide.with(this).load(imagePath).asBitmap().into(100, 100).get();
You can try this way:
Glide.with(this)
.load(Uri.fromFile(new File(url)))
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
bitmapByGlide = resource;
}
});
(use Uri.formFile() is trick of this)
Try this.
Glide.with(this)
.load(url)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
}
});
private SimpleTarget target = new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
// do something with the bitmap
// for demonstration purposes, let's just set it to an ImageView
imageView1.setImageBitmap( bitmap );
}
};
private void loadImageSimpleTarget() {
Glide
.with( context ) // could be an issue!
.load( eatFoodyImages[0] )
.asBitmap()
.into( target );
}
Source: https://futurestud.io/tutorials/glide-callbacks-simpletarget-and-viewtarget-for-custom-view-classes
try this:
File b = new File(Environment.getExternalStorageDirectory(), "DCIM/Camera/IMG_20150828_174009.jpg");
and
Glide.with(MainActivity.this).load(b).error(R.drawable.empty_pic).placeholder(R.drawable.empty_pic).into(image2);
I have a RecyclerView with CardViews inside a staggered grid layout. Each CardView has a custom adjustable height ImageView inside. I am using Picasso to load images into the ImageView.
I am trying to first transform the image to match the width of the ImageView and set the height so that aspect ratio is maintained. I am then trying to resize the height of ImageView to match the image.
Everything works on the first load but when I scroll down my custom transformation isn't able to get the width of the ImageView it just returns 0 and this causes the app to crash.
I tried with a getViewTreeObserver like suggested in this post but then only the first four pictures load, the next few images are blank, and then the first four images repeat themselves in the wrong CardViews.
Here is the code I have that loads properly but crashes on scroll:
Recycler Adapter
public class PlacesRecyclerAdapter extends
RecyclerView.Adapter<PlacesRecyclerAdapter.PlacesView> {
...
#Override
public void onBindViewHolder(final PlacesView placesView, final int i) {
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
float ratio = (float) bitmap.getHeight() / (float) bitmap.getWidth();
placesView.placeImage.setAspectRatio(ratio);
placesView.placeImage.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
placesView.placeImage.setTag(target);
// Setup details variables
final Business place = mPlaces.get(i);
String photo = place.getImage_url();
// Load Image with Picasso
Picasso.with(mContext)
.load(photo)
.transform(new FitToViewTransformation(placesView.placeImage))
.into(target);
}
...
}
Custom Transformation
public class FitToViewTransformation implements Transformation {
private DynamicHeightImageView mView;
public FitToViewTransformation(DynamicHeightImageView view) {
mView = view;
}
#Override
public Bitmap transform(Bitmap source) {
int targetWidth = mView.getWidth(); // This returns the width on the first page load but on scrolling returns 0
Log.v("FitToView:", "Target width: " + targetWidth);
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
int targetHeight = (int) (targetWidth * aspectRatio);
Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
// Same bitmap is returned if sizes are the same
source.recycle();
}
return result;
}
#Override
public String key() {
return "transformation" + " desiredWidth";
}
}
Update 1 (failure)
I went ahead and tried the OnGlobalLayoutListener again and I still get just the first four images then four blank images, then the first four showing again. This is how I implemented it in my onBindViewHolder:
placesView.placeImage.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
placesView.placeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Picasso.with(mContext)
.load(photo)
.placeholder(R.drawable.cast_album_art_placeholder)
.error(R.drawable.item_icon_parking)
.transform(new FitToViewTransformation(placesView.placeImage))
.into(target);
}
});
Update 2 (success... I guess)
So I have found a fix, although I'm not so sure it is the right thing to do. It does work though and the app doesn't have any unwanted behavior. All I did was add an empty while loop to the beginning of my transform method like this:
#Override
public Bitmap transform(Bitmap source) {
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
while(mView.getWidth() == 0) {
}
int targetWidth = mView.getWidth();
Log.v("FitToView:", "Target width: " + targetWidth);
int targetHeight = (int) (targetWidth * aspectRatio);
Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
// Same bitmap is returned if sizes are the same
source.recycle();
}
return result;
}
I'm looking to adopt the Glide library in place of Universal Image Loader but I'm running into a problem with regards to shared element transitions.
In my simple Sandbox I've created the following transition using UIL: https://dl.dropboxusercontent.com/u/97787025/device-2015-06-18-113333.mp4
Pretty simple, and it works fine. But when I used Glide, it doesn't look so nice: https://dl.dropboxusercontent.com/u/97787025/device-2015-06-18-114508.mp4
Here is the code I'm using
The first activity:
public class MainActivity extends BaseActivity {
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
final ImageView iv = (ImageView) findViewById(R.id.main_image);
displayImageGlide(BaseActivity.IMAGE_URL, iv, true);
Button button = (Button) findViewById(R.id.main_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), DifferentActivity.class);
startActivity(intent, iv);
}
});
}
}
And the second:
public class DifferentActivity extends BaseActivity {
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.different);
ImageView imageView = (ImageView) findViewById(R.id.diff_image);
displayImageGlide(BaseActivity.IMAGE_URL, imageView, false);
}
}
BaseActivity just contains displayImageGlide
public void displayImageGlide(String url, ImageView imageView) {
Glide.with(this).load(url)
.asBitmap().transform(new CustomTransformation(this))
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView);
}
private static class CustomTransformation extends BitmapTransformation {
public CustomTransformation(Context context) {
super(context);
}
#Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return bitmapChanger(toTransform, outWidth, outHeight);
}
#Override
public String getId() {
return "some_id_1";
}
}
private static Bitmap bitmapChanger(Bitmap bitmap, int desiredWidth, int desiredHeight) {
float originalWidth = bitmap.getWidth();
float originalHeight = bitmap.getHeight();
float scaleX = desiredWidth / originalWidth;
float scaleY = desiredHeight / originalHeight;
//Use the larger of the two scales to maintain aspect ratio
float scale = Math.max(scaleX, scaleY);
Matrix matrix = new Matrix();
matrix.setScale(scale, scale);
//If the scaleY is greater, we need to center the image
if(scaleX < scaleY) {
float tx = (scale * originalWidth - desiredWidth) / 2f;
matrix.postTranslate(-tx, 0f);
}
Bitmap result = Bitmap.createBitmap(desiredWidth, desiredHeight, bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(bitmap, matrix, new Paint());
return result;
}
I've tried removing the cache lines from the Glide builder (used to prevent it from caching what I'm trying to tweak) but that didn't help. Would love to adopt Glide, but it's kind of a deal breaker if this won't work. If anyone has some input I'd appreciate it, thanks!
I tried your code and got the same result, then I tried another implementation following this: https://github.com/codepath/android_guides/wiki/Shared-Element-Activity-Transition
And made some changes, which I think are the key here:
The centerCrop should be set on the ImageView, if we set it with Glide it causes the same bug.
activity_main.xml
<ImageView
android:id="#+id/ImageView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:transitionName="detail_image"
android:scaleType="centerCrop"
/>
BaseActivity.java
On the MainActivity dontTransform should be true and on DifferentActivity false.
public void displayImageGlide(String url, ImageView imageView, Boolean dontTransform) {
if (dontTransform) {
Glide.with(this).load(url)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.dontTransform()
.into(imageView);
return;
}
Glide.with(this).load(url)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView);
}
Edit, see how it looks: https://www.dropbox.com/s/30s5l8awxogltls/device-2015-06-23-153153.mp4?dl=0
For those of you that are struggling with the SharedElementTransition using Glide I think I got a workaround that works, or at least it worked for me. In your second activity or fragment use this code:
postponeEnterTransition();
GlideApp.with(this)
.load(imageToLoad)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
startPostponedEnterTransition();
return false;
}
})
.into(imageView);
If you are targeting API<21 use:
supportPostponeEnterTransition();
supportStartPostponedEnterTransition();
Hope that helps!