本篇文章主要介绍了" UWP开发中两种网络图片缓存方法",主要涉及到方面的内容,对于Windows Phone开发感兴趣的同学可以参考一下:
通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快。 假...
通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快。
假如你已经知道了某一张图片的地址,那么第一件事就是要把这张图片下载下来;当然如果是一次性读取的话,可以直接把图片地址给Image控件或者给Bitmapimage对象(实际上这二者是没有去别的),但这无法存到本地,只作为显示用;但是我们要做的是保存到本地,这样肯定是不行的。现在我们就要用到HTTP的东西了,请看下面的代码:
asyncstaticpublic Task GetStreamAsync(string url)
{
httpClient = new HttpClient();
var response = await httpClient.GetInputStreamAsync(new Uri(url));
return response;
}
asyncstaticpublic Task GetBufferAsync(string url)
{
httpClient = new HttpClient();
var ResultStr = await httpClient.GetBufferAsync(new Uri(url));
return ResultStr;
}
这两个静态方法分别获取url地址的buffer数据和输入流。有了buffer或者stream之后就可以进行下一步-保存。
当我们下载完成后,首先要做的很有可能是先显示出来,然后再保存,所以先把数据写入到图片对象中:
这里有两种方法:
1.WriteableBitmap
protectedasync Task GetWriteableBitmapAsync(string url)
{
try
{
IBuffer buffer = await GetBufferAsync(url);
if (buffer != null)
{
BitmapImage bi = new BitmapImage();
WriteableBitmap wb = null; Stream stream2Write;
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
stream2Write = stream.AsStreamForWrite();
await stream2Write.WriteAsync(buffer.ToArray(), 0, (int)buffer.Length);
await stream2Write.FlushAsync();
stream.Seek(0);
await bi.SetSourceAsync(stream);
wb = new WriteableBitmap(bi.PixelWidth, bi.PixelHeight);
stream.Seek(0);
await wb.SetSourceAsync(stream);
return wb;
}
}
else
{
returnnull;
}
}
catch
{
returnnull;
}
}
2.SoftwareBitmap
publicasync Task GetSoftwareBitmapAsync(string url)
{
try
{
IInputStream inputStream = await GetSteramAsync(url);
IRandomAccessStream memStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(inputStream, memStream);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memStream);
SoftwareBitmap sb = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
return sb;
}
catch {
returnnull;
}
}
这两种都可以作为展示图像的数据源,其中WriteableBitmap可以直接给Image.Source , SoftwareBitmap这需要转为SoftwareBitmap:
SoftwareBitmapSource sbs = new SoftwareBitmapSource();
sbs.SetBitmapAsync(sb);
接下来就是保存了:WriteableBitmap:
publicasync Task SaveImageAsync(WriteableBitmap image, string filename)
{
try
{
if (image == null)
{
return;
}
Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
if (filename.EndsWith("jpg"))
BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
elseif (filename.EndsWith("png"))
BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
elseif (filename.EndsWith("bmp"))
BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
elseif (filename.EndsWith("tiff"))
BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
elseif (filename.EndsWith("gif"))
BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
var folder = await _local_folder.CreateFolderAsync("images_cache", CreationCollisionOption.OpenIfExists);
var file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
Stream pixelStream = image.PixelBuffer.AsStream();
byte[] pixels = newbyte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)image.PixelWidth,
(uint)image.PixelHeight,
96.0,
96.0,
pixels);
await encoder.FlushAsync();
}
}
catch
{
}
}