为什么 Glide 加载的图像在 RecyclerView 中被降采样到低分辨率?
Why images loaded by Glide get downsampled to low resolution in a RecyclerView?
我在我的应用程序中从 Picasso
切换到 Glide
。我有一个 RecyclerView
,每一项都是 CustomView
。这个CustomView
根据不同的数据源动态添加TextView
或ImageView
。
A FillWidthImageView
用于显示这些图像,它会自动填充屏幕宽度。当我使用 Picasso
时,效果很好。但是,当我使用 Glide
加载图像时,显示在 FillWidthImageView
中的图像看起来像一个分辨率极低的马赛克,因为它被严重缩减采样。
如果我改用普通 ImageView
,加载图像的大小与占位符相同,图像看起来仍然像马赛克。如果没有占位符,图像在屏幕上看起来很小。如果我在空白 Activity
中显示图像,它们将以全分辨率和正确尺寸加载。
在我的 CustomView
中添加 ImageView
的代码(扩展 LinearLayout
),在 RecyclerView.onCreateViewHolder()
中调用
public void addImageView() {
ImageView imageView = new FillWidthImageView(getContext());
imageView.setPadding(0, 0, 0, 10);
imageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
addView(imageView);
}
代码FillWidthImageView
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable drawable = getDrawable();
if (drawable != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int diw = drawable.getIntrinsicWidth();
if (diw > 0) {
int height = width * drawable.getIntrinsicHeight() / diw;
setMeasuredDimension(width, height);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
加载图片的代码,在RecyclerView.onBindItemViewHolder()
中调用
Glide.with(getContext()).load(url).into(imageView);
与 Picasso 相比,Glide 加载的图像质量较差,因为 Glide 的默认位图格式设置为 RGB_565 并且与 ARGB_8888 相比,它仅消耗 50% 的内存占用。
如您在此 video.
中所见,这使得 Glide 比 Picasso 更快
好消息是您可以通过创建一个从 GlideModule 扩展的新 class 将位图格式切换为 ARGB_8888 :-
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
并在清单中添加元数据字段
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
您可以在 Glide wiki 的 glide 配置页面上阅读更多相关信息,当您从 Picasso 切换过来时,您会发现 this 有趣的读物
谢谢@Hitesh Kr Sahu,不过我已经自己解决了这个bug。这是因为 Glide 没有获得我的 CustomView
包装器的正确尺寸。我通过调用 .override(int,int)
和 .fitCenter()
应用维度解决了这个错误。我将屏幕的宽度和高度传递给它,因此它会根据屏幕尺寸进行缩放。
我在我的应用程序中从 Picasso
切换到 Glide
。我有一个 RecyclerView
,每一项都是 CustomView
。这个CustomView
根据不同的数据源动态添加TextView
或ImageView
。
A FillWidthImageView
用于显示这些图像,它会自动填充屏幕宽度。当我使用 Picasso
时,效果很好。但是,当我使用 Glide
加载图像时,显示在 FillWidthImageView
中的图像看起来像一个分辨率极低的马赛克,因为它被严重缩减采样。
如果我改用普通 ImageView
,加载图像的大小与占位符相同,图像看起来仍然像马赛克。如果没有占位符,图像在屏幕上看起来很小。如果我在空白 Activity
中显示图像,它们将以全分辨率和正确尺寸加载。
在我的 CustomView
中添加 ImageView
的代码(扩展 LinearLayout
),在 RecyclerView.onCreateViewHolder()
public void addImageView() {
ImageView imageView = new FillWidthImageView(getContext());
imageView.setPadding(0, 0, 0, 10);
imageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
addView(imageView);
}
代码FillWidthImageView
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable drawable = getDrawable();
if (drawable != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int diw = drawable.getIntrinsicWidth();
if (diw > 0) {
int height = width * drawable.getIntrinsicHeight() / diw;
setMeasuredDimension(width, height);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
加载图片的代码,在RecyclerView.onBindItemViewHolder()
Glide.with(getContext()).load(url).into(imageView);
与 Picasso 相比,Glide 加载的图像质量较差,因为 Glide 的默认位图格式设置为 RGB_565 并且与 ARGB_8888 相比,它仅消耗 50% 的内存占用。
如您在此 video.
中所见,这使得 Glide 比 Picasso 更快好消息是您可以通过创建一个从 GlideModule 扩展的新 class 将位图格式切换为 ARGB_8888 :-
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
并在清单中添加元数据字段
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
您可以在 Glide wiki 的 glide 配置页面上阅读更多相关信息,当您从 Picasso 切换过来时,您会发现 this 有趣的读物
谢谢@Hitesh Kr Sahu,不过我已经自己解决了这个bug。这是因为 Glide 没有获得我的 CustomView
包装器的正确尺寸。我通过调用 .override(int,int)
和 .fitCenter()
应用维度解决了这个错误。我将屏幕的宽度和高度传递给它,因此它会根据屏幕尺寸进行缩放。