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

时间:2013-11-09 19:28:54

标签: java android image whatsapp image-loading

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

enter image description here

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

4 个答案:

答案 0 :(得分:2)

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

我在Zingoo做了这件事,然后就blog post做了一个。使用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类。

答案 1 :(得分:2)

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

基本上,您需要做的就是在创建.setProgressiveRenderingEnabled(true)时调用ImageRequest。我已将Fresco渐进式JPEG流媒体的完整示例包含在此demo application中提及的answer中,您可能需要尝试一下以了解其工作原理。

对于懒惰的人:在使用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中所述。

答案 2 :(得分: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();

答案 3 :(得分:0)

使用Glide lib:

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