vue 获取图片宽度和高度尺寸_Android 利用 Glide 获取图片的实际尺寸

本文介绍了如何在Android中使用Glide获取网络图片的实际尺寸,以及在Vue中处理图片尺寸的问题。通过实例展示了Glide加载图片时出现的显示尺寸与实际尺寸不符的情况,并提供了获取图片真实尺寸的解决方案。同时,文章讨论了不同场景下图片尺寸处理的策略,包括省流模式下的占位图处理和避免OOM的问题。
摘要由CSDN通过智能技术生成

最近有个群友提了一个挺有意思的问题,当使用 Glide 加载图片时,假如不设置 ImageView 的宽高,会出现显示不可控的情况。

什么意思呢?我们来复现一下他的情况。

这位群友为我们提供了一张表情包图片:

b10c1c890274bf6638809d9671c2c9ba.png

要不是我们是正儿八经的学术讨论群,可能这位群友已经被锤死了…

当然,这个表情包是使用一个 URL 提供的,实际上只是相当于模拟从后端获取图片时的场景,因为一般这种情况后端是不会特意将图片尺寸提供给我们的,其实你也可以将图片放在 Assets Folder 中,同样能够复现,但别放在 /res/drawable 或者 /res/mipmap 文件夹内,因为系统会根据屏幕分辨率对其进行缩放。

我先把这张图片下载下来,看一下它的实际尺寸:

a92b91f508722281529491a8d28fda31.png

可以看到这张图片的尺寸为 100 × 97 像素,并不大,我们在项目中实际加载看看。

首先随便写一个简单的布局用于加载这张图片:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/background_dark"tools:context=".MainActivity">
    <ImageViewandroid:id="@+id/image"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />
androidx.constraintlayout.widget.ConstraintLayout>

因为『Android Studio』新建项目时默认就采用了约束布局,那我这里就不做修改了,让 ImageView 置于屏幕的中央,因为群友提到不设置宽高,所以这里宽高我都定为 wrap_content,另外由于表情包是白底的,所以我给了一个深色的背景以更好的看出其显示边界。

为了对比,我要采用两种加载方式,一种是原生 API 的加载,另一种就是 Glide

原生加载方式不复杂,通过 URL 获取流并将其解码为 Bitmap 即可:

public class MainActivity extends AppCompatActivity {

    String url = "http://wx4.sinaimg.cn/bmiddle/b64da6adly1gjbwvv4es7j202s02p0sk.jpg";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        final ImageView imageView = findViewById(R.id.sticker);
        new Thread(() -> {
            try {
                final Bitmap bitmap = BitmapFactory.decodeStream(new URL(url).openStream());
                runOnUiThread(() -> imageView.setImageBitmap(bitmap));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

需要注意的是由于我们是加载网络图片,尽管我们并没有显式的写出网络请求的代码,它实际上是做了网络请求的,所以我们不能在主线程中执行,而将图片加载到 ImageView 时是 UI 操作,又需要切回到主线程。

Glide 的加载方式更加简单,之前『一次实战爱上「Glide」』一文也做了详细的介绍,而且因为 Glide 内部已经帮我们做了处理,所以我们不再需要关心线程的问题了,一行代码搞定:

public class MainActivity extends AppCompatActivity {

    String url = "http://wx4.sinaimg.cn/bmiddle/b64da6adly1gjbwvv4es7j202s02p0sk.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        final ImageView imageView = findViewById(R.id.sticker);
        Glide.with(this).load(url).into(imageView);
    }
}

结果的确如群友所说,Glide 加载的图片显示的并不是实际尺寸:

c6a7baa44aa8a2749d16ae7c314d0ab8.png25083e33b12a92c290ae736d3286308b.png
图片实际大小Glide 加载出来的大小

我们监听一下 Glide 加载出来的尺寸:

Glide.with(this)
        .asBitmap()
        .load(url)
        .listener(new RequestListener() {@Overridepublic boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {return false;
            }@Overridepublic boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { int width = resource.getWidth();int height = resource.getHeight();
                Log.d(TAG, "Width: " + width);
                Log.d(TAG, "Height: " + height);return false;
            }
        })
        .into(imageView);

好家伙,加载的尺寸为 2139 × 2075 像素,这明显不对劲呀。其实这并不是图片的尺寸大小,而是加载图片后的 ImageView 的大小,也就是图片显示时的大小。

那我们能否获取到图片的实际尺寸呢?

当然可以。

Glide.with(this)
        .asBitmap()
        .load(url)
        .into(new SimpleTarget() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) { int realWidth = resource.getWidth();int realHeight = resource.getHeight();
                Log.d(TAG, "Real Width: " + realWidth);
                Log.d(TAG, "Real Height: " + realHeight);
            }
        });

这里获取到的尺寸就是实际的 100 × 97 像素了。

然后你可能会发现,这个获取实际尺寸的方法是在 into() 里面的,那没有把 ImageView 实例传进去,它不能够加载我们的图片啊。

其实我们只需要用回最原始的方法即可:

Glide.with(this)
        .asBitmap()
        .load(url)
        .into(new SimpleTarget() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
                imageView.setImageBitmap(resource);
            }
        });

当然你不嫌麻烦的话也可以用 Glide 重新加载一遍:

Glide.with(this)
        .asBitmap()
        .load(url)
        .into(new SimpleTarget() {@Overridepublic void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
                Glide.with(imageView)
                        .load(resource)
                        .override(resource.getWidth(), resource.getHeight())
                        .into(imageView);
            }
        });

说实话这种应用场景我至今还没有遇到过,总感觉 ImageView 不确定尺寸的话很容易会产生屏幕适配问题。

但转念一想,在微信聊天界面的表情包似乎是可以根据图片尺寸显示的,应该存在一个阈值,当表情包的尺寸大于等于这个阈值时,按照这个阈值缩放显示,当表情包的尺寸小于这个阈值时,就按照实际大小显示。

由于上面的场景我们只处理了小图加载的问题,因此上面的方法不能够直接应用到项目中,否则加载大图的时候也会产生不可控,更甚的是大图还容易造成 OOM。

而另一种场景,一些 App 有省流模式的功能,可以只显示文字而不加载图片,但是其显示的占位图和实际图片的宽高是一致的,这种就不能使用上面的方法来处理了,因为使用了上面的方法就会去请求图片,也就达不到省流的目的,理论上应由后端将图片的尺寸返回,再由客户端生成占位图。

f2587d3ae8ff056c1702d5dcc7750bc3.png

875a7db341f793390e0566714bf8a7c0.png 03a87f21caa77cf6af25a83794011020.png

Like it or not
I am here

0c294d6b2e40afbce75b0c997715e079.png c4e23aea3798391e2624a2d2ed7eb984.png

690d79e795fe4fa76668a8270cd9b100.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值