As a web app, accessing remote images is a common feature. WP itself provides good support for displaying images through the image Uri.
Public imagesource source {Get; set ;}
<Image Source = "https://www.google.com/intl/en_com/images/srpr/logo3w.png"/>
To reduce network traffic, You Need To Cache images to local data storage. Review WP's local data storage:
Windows Phone local data storage
Windows Phone applications can store data locally using independent storage. Applications can store data in three ways:
- Set: Use the isolatedstoragesettings class to store data as key/value pairs.
- Files and folders: Use the isolatedstoragefile class to store files and folders.
- Local Database: 7.1 is added. It only supports LINQ to SQL and cannot write SQL statements.
Local Image Storage
First, you should select isolatedstoragefile for Image Storage:
WP provides a stream called isolatedstoragefilestream with the same operations as filestream.
using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
Cache ideas
The idea is to first check whether the folder is cached. First, define a public cache folder and create a folder in the static constructor.
Private const string cachedirectory = "cachedimages ";
Static storagecachedimage ()
{
// Create a cache directory
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
{
If (! Isolatedstoragefile. directoryexists (cachedirectory ))
{
Isolatedstoragefile. createdirectory (cachedirectory );
}
}
}
Then convert the URL into a file name. My method is simple and you can directly replace the '/' symbol. Use fileexists to determine whether a file exists
// File path
Filepath = path. Combine (cachedirectory, urisource. absolutepath. trimstart ('/'). Replace ('/','_'));
/// <Summary>
/// Open the cache Source
/// </Summary>
Private void opencatchsource ()
{
Bool exist;
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
{
Exist = isolatedstoragefile. fileexists (filepath );
}
If (exist)
{
Setcachestreamsource ();
}
Else
{
Setwebstreamsource ();
}
}
If no cache is available, download the image through Uri and save it to isolatedstoragefile.
Download using httpwebrequest and use isolatedstoragefilestream to save images
/// <Summary>
/// Download the image in the URI
/// </Summary>
Private void setwebstreamsource ()
{
VaR httpwebrequest = (httpwebrequest) webrequest. Create (urisource );
Httpwebrequest. allowreadstreambuffering = true;
Httpwebrequest. begingetresponse (responsecallback, httpwebrequest );
}
/// <Summary>
/// Download callback
/// </Summary>
/// <Param name = "asyncresult"> </param>
Private void responsecallback (iasyncresult asyncresult)
{
VaR httpwebrequest = asyncresult. asyncstate as httpwebrequest;
If (httpwebrequest = NULL) return;
Try
{
VaR response = httpwebrequest. endgetresponse (asyncresult );
Using (VAR stream = response. getresponsestream ())
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
Using (VAR filestream = isolatedstoragefile. openfile
(Filepath, filemode. openorcreate, fileaccess. Write ))
{
Stream. copyto (filestream); // save to local
}
Dispatcher. begininvoke (setcachestreamsource );
}
Catch (exception ERR)
{
Debug. writeline (ERR. Message );
}
}
Save it to the local file and download it. Use isolatedstoragefilestream to open the local image stream and set the image stream through the setsource of the parent class.
private void SetCacheStreamSource()
{
using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
{
SetSource(stream);
}
The complete code is as follows:
View code
Using system;
Using system. diagnostics;
Using system. IO;
Using system. Io. isolatedstorage;
Using system. net;
Using system. Windows. Media. imaging;
Namespace kimistudio. Controls
{
/// <Summary>
/// Independently store cached image sources
/// </Summary>
Public sealed class storagecachedimage: bitmapsource
{
Private readonly URI urisource;
Private readonly string filepath;
Private const string cachedirectory = "cachedimages ";
Static storagecachedimage ()
{
// Create a cache directory
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
{
If (! Isolatedstoragefile. directoryexists (cachedirectory ))
{
Isolatedstoragefile. createdirectory (cachedirectory );
}
}
}
/// <Summary>
/// Create an image source that stores the cache independently
/// </Summary>
/// <Param name = "urisource"> </param>
Public storagecachedimage (URI urisource)
{
This. urisource = urisource;
// File path
Filepath = path. Combine (cachedirectory, urisource. absolutepath. trimstart ('/'). Replace ('/','_'));
Opencatchsource ();
}
/// <Summary>
/// Open the cache Source
/// </Summary>
Private void opencatchsource ()
{
Bool exist;
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
{
Exist = isolatedstoragefile. fileexists (filepath );
}
If (exist)
{
Setcachestreamsource ();
}
Else
{
Setwebstreamsource ();
}
}
/// <Summary>
/// Set the cache flow to the image
/// </Summary>
Private void setcachestreamsource ()
{
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
Using (VAR stream = isolatedstoragefile. openfile (filepath, filemode. Open, fileaccess. Read ))
{
Setsource (Stream );
}
}
/// <Summary>
/// Download the image in the URI
/// </Summary>
Private void setwebstreamsource ()
{
VaR httpwebrequest = (httpwebrequest) webrequest. Create (urisource );
Httpwebrequest. allowreadstreambuffering = true;
Httpwebrequest. begingetresponse (responsecallback, httpwebrequest );
}
/// <Summary>
/// Download callback
/// </Summary>
/// <Param name = "asyncresult"> </param>
Private void responsecallback (iasyncresult asyncresult)
{
VaR httpwebrequest = asyncresult. asyncstate as httpwebrequest;
If (httpwebrequest = NULL) return;
Try
{
VaR response = httpwebrequest. endgetresponse (asyncresult );
Using (VAR stream = response. getresponsestream ())
Using (VAR isolatedstoragefile = isolatedstoragefile. getuserstoreforapplication ())
Using (VAR filestream = isolatedstoragefile. openfile
(Filepath, filemode. openorcreate, fileaccess. Write ))
{
Stream. copyto (filestream );
}
Dispatcher. begininvoke (setcachestreamsource );
}
Catch (exception ERR)
{
Debug. writeline (ERR. Message );
}
}
}
}
Test
Define an image
Uri urisource = new uri (@ "https://www.google.com/intl/en_com/images/srpr/logo3#png ");
Image1.imagesource = new storagecachedimage (urisource );
View with isostorespy (here is the actual image of my app)