使用 Glide 加载 SVG 时图像变得模糊
Image becomes blurry when loading SVG with Glide
在应用程序中,我使用以下示例将 SVG 图像加载到 ImageView 中:
Glide.with(context)
.using(Glide.buildStreamModelLoader(Uri.class, context), InputStream.class)
.from(Uri.class)
.as(SVG.class)
.transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
.sourceEncoder(new StreamEncoder())
.cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder()))
.decoder(new SvgDecoder())
.listener(new SvgSoftwareLayerSetter())
.diskCacheStrategy(DiskCacheStrategy.NONE)
.load(uri)
.into(imageView);
xml 中的 ImageView 如下所示:
<ImageView
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginTop="25dp"
android:layout_gravity="center"
/>
因此,可以在下图中看到问题。右边的图标是从应用程序的资源中设置的,而左边的图标是使用 Glide 从服务器加载的。由于某种原因,图像未正确缩放并且看起来很模糊。
我已经尝试过这个答案的解决方案:
,但是没用。
升级到 glide v4 后问题解决了。现在我使用以下代码加载 svg:
GlideApp.with(context)
.as(PictureDrawable.class)
.transition(withCrossFade())
.fitCenter()
.listener(new SvgSoftwareLayerSetter())
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE))
.load(uri).into(imageView);
在我的 AppGlideModule 中我有:
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) {
registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
.prepend(SVG.class, new SvgEncoder())
.append(InputStream.class, SVG.class, new SvgDecoder());
}
SvgDrawableTranscoder 使用一种简单的方法将 SVG 转换为 PictureDrawable:
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
@Override
public Resource<PictureDrawable> transcode(@NonNull Resource<SVG> toTranscode, @NonNull Options options) {
SVG svg = toTranscode.get();
Picture picture = svg.renderToPicture();
PictureDrawable drawable = new PictureDrawable(picture);
return new SimpleResource<>(drawable);
}
}
这就是我实现 SvgEncoder 的方式 class:
public class SvgEncoder implements ResourceEncoder<SVG>{
@NonNull
@Override
public EncodeStrategy getEncodeStrategy(@NonNull Options options) {
return EncodeStrategy.SOURCE;
}
@Override
public boolean encode(@NonNull Resource<SVG> data, @NonNull File file, @NonNull Options options) {
try {
SVG svg = data.get();
Picture picture = svg.renderToPicture();
picture.writeToStream(new FileOutputStream(file));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
对于 Android VectorDrawables, surprisingly the following worked for me (see this post):
Glide.with(context).load(myImage).dontTransform().into(myView);
在应用程序中,我使用以下示例将 SVG 图像加载到 ImageView 中:
Glide.with(context)
.using(Glide.buildStreamModelLoader(Uri.class, context), InputStream.class)
.from(Uri.class)
.as(SVG.class)
.transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
.sourceEncoder(new StreamEncoder())
.cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder()))
.decoder(new SvgDecoder())
.listener(new SvgSoftwareLayerSetter())
.diskCacheStrategy(DiskCacheStrategy.NONE)
.load(uri)
.into(imageView);
xml 中的 ImageView 如下所示:
<ImageView
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginTop="25dp"
android:layout_gravity="center"
/>
因此,可以在下图中看到问题。右边的图标是从应用程序的资源中设置的,而左边的图标是使用 Glide 从服务器加载的。由于某种原因,图像未正确缩放并且看起来很模糊。
我已经尝试过这个答案的解决方案:
升级到 glide v4 后问题解决了。现在我使用以下代码加载 svg:
GlideApp.with(context)
.as(PictureDrawable.class)
.transition(withCrossFade())
.fitCenter()
.listener(new SvgSoftwareLayerSetter())
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE))
.load(uri).into(imageView);
在我的 AppGlideModule 中我有:
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, Registry registry) {
registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
.prepend(SVG.class, new SvgEncoder())
.append(InputStream.class, SVG.class, new SvgDecoder());
}
SvgDrawableTranscoder 使用一种简单的方法将 SVG 转换为 PictureDrawable:
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
@Override
public Resource<PictureDrawable> transcode(@NonNull Resource<SVG> toTranscode, @NonNull Options options) {
SVG svg = toTranscode.get();
Picture picture = svg.renderToPicture();
PictureDrawable drawable = new PictureDrawable(picture);
return new SimpleResource<>(drawable);
}
}
这就是我实现 SvgEncoder 的方式 class:
public class SvgEncoder implements ResourceEncoder<SVG>{
@NonNull
@Override
public EncodeStrategy getEncodeStrategy(@NonNull Options options) {
return EncodeStrategy.SOURCE;
}
@Override
public boolean encode(@NonNull Resource<SVG> data, @NonNull File file, @NonNull Options options) {
try {
SVG svg = data.get();
Picture picture = svg.renderToPicture();
picture.writeToStream(new FileOutputStream(file));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
对于 Android VectorDrawables, surprisingly the following worked for me (see this post):
Glide.with(context).load(myImage).dontTransform().into(myView);