8

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

在此处输入图像描述

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

4

4 回答 4

2

彩色占位符解决方案还有另一种替代方案,即在加载真实图像之前显示缩略图(可能只有 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() {
        }
    });

帖子本身的更多细节,包括 Blur 类。

于 2015-02-15T13:14:34.630 回答
2

旧帖子的另一个最新答案。您可以尝试Fresco库的渐进式 JPEG 流式传输功能来实现该效果。

基本上,您需要做的就是.setProgressiveRenderingEnabled(true)在创建ImageRequest. 我在这个答案中提到的演示应用程序中包含了 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);

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

于 2016-06-26T14:25:48.007 回答
1

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

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();
于 2013-11-22T11:26:35.247 回答
0

使用 Glide 库:

Glide.with(context)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .into(imageView);
于 2018-10-15T10:50:09.107 回答