之后如何在 android 中加载低质量然后高质量的图像(就像 WhatsApp 个人资料图像一样)

Posted

技术标签:

【中文标题】之后如何在 android 中加载低质量然后高质量的图像(就像 WhatsApp 个人资料图像一样)【英文标题】:How to load low quality and then high quality image afterwards in android (just like WhatsApp profile image) 【发布时间】:2017-06-27 04:21:16 【问题描述】:

我正在寻找一种我可以使用的设计模式,以便在 android recyclerView 中以低质量快速加载图像,然后调用高质量图像将 之后改写低质量的图像。我经常看到先加载低质量图像然后再加载高质量图像的情况。

但是这是如何在回收器视图的适配器中完成的。现在我正在使用 picasso 进行缓存和图像加载。所以例如这里是一个低质量图像的链接:

http://example.com/lowQuality.jpg 和同样高质量的http://example.com/highQuality.jpg

如果我在视图中执行此操作,那么在我的 recyclerView 适配器中:

public class SearchItemHolder extends RecyclerView.ViewHolder  

        @BindView(R.id.iv)
        ImageView iv;

        @BindView(R.id.tv_description)
        TextView tv_description;

        public SearchItemHolder(View view) 
            super(view);
            ButterKnife.bind(this, view);
        

        public void bindSearch(final SearchModel searchModel) 

            String description = searchModel.getProductName();
            final String imageLowQualityIDUrl = searchModel.getIdLowQualityImage();
            final String imageHighQualityIDUrl = searchModel.getIdHighQualityImage();

            tv_price.setText(price);
            tv_description.setText(description);



            Picasso.with(mContext).load(imageLowQualityIDUrl).into(iv);
//but how to switch it to high quality URL after its finished loading ?


        
    

为了清楚起见,我希望只要尚未加载高质量图像,就可以首先显示低质量图像。

更新:我真正想要的是我在应用程序上看到的效果,其中低质量的图像加载速度很快,然后在几秒钟后它转换为更高的质量。如果有其他工具或方法可以做到这一点,请告诉我。我想要与 whatsapp 个人资料图像相同的效果(它如何从劣质变为优质)。

【问题讨论】:

你的意思是有两个版本的图片,低质量和高质量然后你想先加载低质量,然后再加载高质量? 你为什么不先尝试加载高质量,然后调整为低质量。如果您使用这种设计模式,假设这两个图像分别为 45kb 和 90kb,如果加载一次,则调整 90kb 的数据大小,如果加载两次,则为 135kb 的两个图像。 我真正想要的是我在应用程序上看到的效果,其中低质量图像加载速度很快,然后在几秒钟后它转换为更高质量 我发布了一个可能的答案,如果它适合你,请告诉我 我明白了你的想法!我对此也很感兴趣。我喜欢 Flickr 的 android 应用程序这样做的方式。首先,Feed 中加载了低图像,经过一段时间的延迟后,只有当前可见的图片以更高分辨率更新。如果您愿意,我们可以配合这次调查以获得更好的结果)) 【参考方案1】:

我找到了Glide 的解决方案。 您可以指定要加载为缩略图的低分辨率图像。您只需要:

private void loadImageThumbnailRequest()   
// setup Glide request without the into() method
DrawableRequestBuilder<String> thumbnailRequest = Glide
    .with( context )
    .load( yourData.getLowQualityLink() );

// pass the request as a a parameter to the thumbnail request
Glide
    .with( context )
    .load( yourData.getHdUrl() )
    .thumbnail( thumbnailRequest )
    .into( imageView );

更多信息在source这里

【讨论】:

Fresco 在消除内存不足问题方面效果更好,所以我更喜欢它。但无论如何,你在这里有一个关于滑行实施的问题。这是否意味着我的服务器应该有一个低质量的图像。所以任何时候我想做这个效果,我的服务器都应该有高质量和低质量的图像,正如 Vivee Omomi 提到的那样。对吗? 是的,您的服务器必须提供不同质量和不同 url 的图像。加载时间的利润。使用低质量的缩略图,您的 RecyclerView 将更快地加载图像,然后在拇指“顶部”加载高清图像。在那种情况下,用户体验会很棒。而且,如果您只是“模仿”这种行为,由于图像大小调整,加载时间会以某种方式增加。正如我理解的那样,这将是多余的操作。【参考方案2】:

我想我明白了,您想要的效果就像 WhatsApp 个人资料图片一样。我认为该过程取决于您的后端,您的后端应该有一种方法可以默认调整/压缩原始图片的大小,另一种方法可以保留原始大小的图片。

服务器伪代码示例

$image = image.jpg

$requestLowQuality = resizeThis($image)

 $requestHighQuality = $image.

因此,当您的应用在后台加载图片时,$requestLowQuality 的异步任务请求会加载低质量的默认版本。但是当用户点击查看时,一个 Asynctask 向服务器请求 $requestHighQuality

我认为这就是 WhatsApp 的做法。这就是为什么你必须等待一段时间才能让模糊的图片变成高质量的。

Picasso 只会根据请求方法加载图像

祝你好运

【讨论】:

whatsapps 个人资料图片究竟是如何做到的。你的权利。但这比你写的更复杂,我想。因为可以说高质量请求在低质量请求之前完成。那么我需要取消低质量请求等。可能存在时间问题 您说的非常对,可能存在时间问题。但这仅适用于服务器立即对调用进行操作的情况。服务器必须已经在存储中准备了这些图像,无论是调整大小还是正常质量,我认为这个过程只适用于可以覆盖的单张图片。使用 onclick 侦听器和后台任务对服务器的不同请求怎么样,您可以设置一条消息让用户等待并使这些任务相互依赖。一个工作,另一个等待,反之亦然【参考方案3】:

我还从 Fresco 发现了如何做到这一点:

Uri lowResUri, highResUri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setLowResImageRequest(ImageRequest.fromUri(lowResUri))
    .setImageRequest(ImageRequest.fromUri(highResUri))
    .setOldController(mSimpleDraweeView.getController())
    .build();
mSimpleDraweeView.setController(controller);

似乎和滑翔的想法一样。此信息来自壁画docs。

【讨论】:

以上是关于之后如何在 android 中加载低质量然后高质量的图像(就像 WhatsApp 个人资料图像一样)的主要内容,如果未能解决你的问题,请参考以下文章

加载 UIImage 低质量

网站如何解决图片过大加载慢的问题?

录制高清视频,保存低质量视频

Android:WebView 中加载的图像中的像素质量降低

提高低质量扫描图像的OCR质量

防止视频在移动设备上下载某些源