部分加载来自URL的图像,就像在WhatsApp中实现的那样

WhatsApp开发人员最近改进了图像加载,其中立即加载图像的某些部分(获取其尺寸和图像的一些像素),然后在加载整个图像后,用完整图像替换占位符:

在此处输入图像描述

我的问题是,他们是如何实现的? 他们是通过读取标题(元数据)来读取图像的维度吗? 图像内容怎么样? 或者他们在服务器端有两个版本的图像,一个是低质量的,首先加载的是一个较大的一个是完整的图像? 请注意,如果它是第二种方法,那么一旦从发送方接收图像,它们仍然需要在服务器端提取较小版本的图像。 还有其他方法吗?

彩色占位符解决方案的另一种替代方案是显示缩略图 (可能只有100 X 100像素)作为占位符,直到加载真实图像,这比只有彩色占位符:)更冷。

我是在Zingoo做的, 并发了一篇关于它的博客文章 。 使用Picasso ,你可以这样做:

Transformation blurTransformation = new Transformation() { @Override public Bitmap transform(Bitmap source) { Bitmap blurred = Blur.fastblur(LiveImageView.this.context, source, 10); source.recycle(); return blurred; } @Override public String key() { return "blur()"; } }; Picasso.with(context) .load(thumbUrl) // thumbnail url goes here .placeholder(R.drawable.placeholder) .resize(imageViewWidth, imageViewHeight) .transform(blurTransformation) .into(imageView, new Callback() { @Override public void onSuccess() { Picasso.with(context) .load(url) // image url goes here .resize(imageViewWidth, imageViewHeight) .placeholder(imageView.getDrawable()) .into(imageView); } @Override public void onError() { } }); 

post本身包括Blur类的更多细节。

另一个旧post的最新答案。 您可以尝试使用Fresco库的渐进式JPEG流式处理function来实现此效果。

基本上,您需要做的就是在创建ImageRequest时调用.setProgressiveRenderingEnabled(true) 。 我已经将Fresco渐进式JPEG流的完整示例包含在本答案中提到的演示应用程序中,您可能想尝试一下它是如何工作的。

对于懒人:在使用Fresco时,创建一个DraweeController ,如下所示:

  ImageRequest imgReq = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url)) .setProgressiveRenderingEnabled(true) .build(); DraweeController controller = Fresco.newDraweeControllerBuilder() .setImageRequest(imgReq) .setOldController(yourDrawee.getController()) .build(); yourDrawee.setController(controller); 

注意:此方法有一些限制,如文档中所述。

经过几次实验,我得到的尺寸没有下载整个图像:

 String address = "image_url"; URL url = new URL(address); URLConnection urlC = url.openConnection(); urlC.connect(); InputStream is = urlC.getInputStream(); for(int i = 0; i < 92; i++) is.read(); nt byte1 = is.read(); int byte2 = is.read(); int width = (byte1 << 8) + byte2; for(int i = 0; i < 10; i++) is.read(); byte1 = is.read(); byte2 = is.read(); int height = (byte1 << 8) + byte2; System.out.println("width = " + width + " | height = " + height); is.close(); 

使用Glide lib:

 Glide.with(context) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(imageView);