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() {
}
});
帖子本身的更多细节,包括 Blur 类。
旧帖子的另一个最新答案。您可以尝试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中所述。
经过几次实验,我在没有下载整个图像的情况下得到了尺寸:
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 库:
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);