Swifty Swift
Swifty Swift

Reputation: 175

How to get original image size by using Glide on Android?

I am loading images from dynamic sources and loading them in my app. However sometimes the images are so small and looks bad in my app. What I want to do is get image size and if it is smaller than 5x5, don't show the ImageView at all.

How to achieve this?

When I use sizeReadyCallback, it returns the size of ImageView instead of image. When I use request listener it returns 0,0.

Glide.with(getContext()).load(imageUrl).listener(new RequestListener<String, GlideDrawable>() {
        @Override
        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            //This returns 0,0
            Log.e("TAG","_width: " + resource.getBounds().width() + " _height:" +resource.getBounds().height());
            return false;
        }
    }).into(ivImage).getSize(new SizeReadyCallback() {
        @Override
        public void onSizeReady(int width, int height) {
            //This returns size of imageview.
            Log.e("TAG","width: " + width + " height: " + height);
        }
    });

Upvotes: 15

Views: 29753

Answers (6)

romariomkk
romariomkk

Reputation: 63

This hacky(in fact not) variant works as intended. As the targetView(which is the parameter for .into()) is not specified in this sequence and .preload() is called, the image is not resized up to the ImageView dimensions or the additional scaleType. You get the raw image with its original sizes, which then is set as the ImageView's source.

val imageView = view.findViewById(...)

Glide
.with(context)
.load(imageURL)
.addListener(object: RequestListener<Drawable> {
   override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean) =
      false

   override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
      resource?.let {
         val width = resource.intrinsicWidth
         val height = resource.intrinsicHeight
         //use these sizes whatever needed for
         imageView.setImageDrawable(resource)
      }
      return false
   }
})
.preload()

Upvotes: 2

Mhammed Khaled
Mhammed Khaled

Reputation: 89

     Glide.with(this)
            .asFile()
            .load("your path url image")
            .into(new SimpleTarget<File>() {
                @Override
                public void onResourceReady(@NonNull File resource, @Nullable 
                    Transition<? super File> transition) {
                    fab_raw.setLabelText(""+resource.length());
                }
            });

Upvotes: -1

thundertrick
thundertrick

Reputation: 1674

Update:

A better solution has been provided by @TWiStErRob in comments: better solution


For Glide v4:

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);
         }
     });

The point is getting the bitmap before set into an ImageView.

Upvotes: 14

msamhoury
msamhoury

Reputation: 333

This question is old, but I stumbled across similar scenario where I needed to check for the original image size. After some digging I found this thread on Github which has the solution.

I will copy the latest (glide v4) solution written by pandasys.

This code is Kotlin but Java folks should have no trouble. The code to do the load would look something like:

Glide.with(activity)
 .`as`(Size2::class.java)
 .apply(sizeOptions)
 .load(uri)
 .into(object : SimpleTarget<Size2>() {
   override fun onResourceReady(size: Size2, glideAnimation: Transition<in Size2>) {
     imageToSizeMap.put(image, size)
     holder.albumArtDescription.text = size.toString()
   }

   override fun onLoadFailed(errorDrawable: Drawable?) {
     imageToSizeMap.put(image, Size2(-1, -1))
     holder.albumArtDescription.setText(R.string.Unknown)
   }
 })

The resusable options are:

private val sizeOptions by lazy {
RequestOptions()
    .skipMemoryCache(true)
    .diskCacheStrategy(DiskCacheStrategy.DATA)}

My size class is approximately:

data class Size2(val width: Int, val height: Int) : Parcelable {
  companion object {
    @JvmField val CREATOR = createParcel { Size2(it) }
  }

  private constructor(parcelIn: Parcel) : this(parcelIn.readInt(), parcelIn.readInt())

  override fun writeToParcel(dest: Parcel, flags: Int) {
    dest.writeInt(width)
    dest.writeInt(height)
  }

  override fun describeContents() = 0

  override fun toString(): String = "$width x $height"

}

Here's the relevant part of my AppGlideModule

 class BitmapSizeDecoder : ResourceDecoder<File, BitmapFactory.Options> {
  @Throws(IOException::class)
  override fun handles(file: File, options: Options): Boolean {
    return true
  }

  override fun decode(file: File, width: Int, height: Int, options: Options): Resource<BitmapFactory.Options>? {
    val bmOptions: BitmapFactory.Options = BitmapFactory.Options()
    bmOptions.inJustDecodeBounds = true
    BitmapFactory.decodeFile(file.absolutePath, bmOptions)
    return SimpleResource(bmOptions)
  }
}:




override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
            registry.prepend(File::class.java, BitmapFactory.Options::class.java, BitmapSizeDecoder())
            registry.register(BitmapFactory.Options::class.java, Size2::class.java, OptionsSizeResourceTranscoder())


class OptionsSizeResourceTranscoder : ResourceTranscoder<BitmapFactory.Options, Size2> {
  override fun transcode(resource: Resource<BitmapFactory.Options>, options: Options): Resource<Size2> {
    val bmOptions = resource.get()
    val size = Size2(bmOptions.outWidth, bmOptions.outHeight)
    return SimpleResource(size)
  }
}

So back to the original question, onResourceReady callback you can check for the width and height and decide what whether you show the image or not

Upvotes: 7

Kishore Reddy
Kishore Reddy

Reputation: 2454

Layout code:
    <ImageView
                android:adjustViewBounds="true"
                android:id="@+id/imageView"
                android:scaleType="fitCenter"
                android:src="@android:drawable/ic_menu_camera"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible" />


     Glide.with(context).load(imgpth).placeholder(R.drawable.bg_loading)
                                .error(R.drawable.bg_loading).into(imageProdctBanner).getSize(new SizeReadyCallback() {
                            @Override
                            public void onSizeReady(int width, int height) {
                                Log.e("width","wdthheight "+width+"  :  "+height);
                                //before you load image LOG height and width that u actually got?
                               // mEditDeskLayout.setImageSize(width,height);
                            }
                        });
working perfect its getting image original size.
Happy coding...

Upvotes: -2

ND1010_
ND1010_

Reputation: 3841

Try this one: i not sure about this but you will do this :

Glide.with(this).load(uri).into(imageView).getSize(new SizeReadyCallback() {
    @Override
    public void onSizeReady(int width, int height) {
        //before you load image LOG height and width that u actually got?
        mEditDeskLayout.setImageSize(width,height);
    }
});

Upvotes: -2

Related Questions