I have a Web image with specified URL, it can be browsed in the browser.
i tried to retrieve it from web url and when program goes to bitmapImage.SetSource(ms);
i get a exception "
ex = {System.Exception: The component cannot be found. (Exception from HRESULT: 0x88982F50)
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream)
at System.Wi...
" i did searched other questions on stackoverflow...but no help on this. any one can help me?
byte array did have data, in the runtime debugging, it returns imageByteArray = {byte[1227]}; my option is that exception occurs when converting byte array to BitmapImage.
in the httpclient wrapper class:
public static async Task<Byte[]> GetWebImageByImageName(string ImageName)
{
//Uri imageServerUril = new Uri(ImageName);
var requestMessage = new HttpRequestMessage(HttpMethod.Get, ImageName);
var responseMessage = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
var responseData = await responseMessage.Content.ReadAsByteArrayAsync();
return responseData;
}
in the view model:
private async void ReadArticleList(int pageNumber)
{
string webURL = "http://....."; // the web URL is no problem
try
{
byte[] imageByteArray = await CollectionHttpClient.GetWebImageByImageName(webURL);//
//Convert it to BitmapImage
using (MemoryStream ms = new MemoryStream(imageByteArray))
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.CreateOptions = BitmapCreateOptions.DelayCreation;
bitmapImage.SetSource(ms); // the exception got here
item.BitImage = bitmapImage;
}
IsLoading = false;
}
catch(Exception ex)
{
if (ex.HResult == -2146233088 && ex.Message.Equals("Response status code does not indicate success: 404 ()."))
{
MessageBox.Show("The network is not set right. Internet cannot be accessed.");
}
else
{
MessageBox.Show("sorry, no data.");
}
IsLoading = false;
}
}
* for Detail *
Article model is in below:
public class Article : INotifyPropertyChanged
{
private long _Id;
public long ID
{
get { return _Id; }
set
{
if (_Id != value)
{
_Id = value;
NotifyPropertyChanged("ID");
}
}
}
private string _subject;
public string Subject
{
get
{
return _subject;
}
set
{
if (_subject != value)
{
_subject = value;
NotifyPropertyChanged("Subject");
}
}
}
private string _words;
public string Words
{
get
{
return _words;
}
set
{
if (_words != value)
{
_words = value;
NotifyPropertyChanged("Words");
}
}
}
private DateTime _publishDate;
public DateTime PublishDate
{
get
{ return _publishDate; }
set
{
if (_publishDate != value)
{
_publishDate = value;
NotifyPropertyChanged("PublishDate");
}
}
}
public List<string> ImagePathList = new List<string>();
public BitmapImage BitImage = new BitmapImage();
private string _firstImage;
public string FirstImage
{
get
{
return _firstImage;
}
set
{
if (_firstImage != value)
{
_firstImage = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
If you just want to display an image from a remote server without saving it, do the following:
imageControl1.Source = new BitmapImage(new Uri("http://delisle.saskatooncatholic.ca/sites/delisle.saskatooncatholic.ca/files/sample-1.jpg", UriKind.Absolute));
If you want to save the image to IsolatedStorage you can do the following:
WebClient webClientImg = new WebClient();
webClientImg.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
webClientImg.OpenReadAsync(new Uri("http://delisle.saskatooncatholic.ca/sites/delisle.saskatooncatholic.ca/files/sample-1.jpg", UriKind.Absolute));
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
isSpaceAvailable = IsSpaceIsAvailable(e.Result.Length);
if (isSpaceAvailable)
{
SaveToJpeg(e.Result);
}
else
{
MessageBox.Show("You are running low on storage space on your phone. Hence the image will be loaded from the internet and not saved on the phone.", "Warning", MessageBoxButton.OK);
}
}
Function to check if IsolatedStorage space is available or else it will not download the image.
private bool IsSpaceIsAvailable(long spaceReq)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
long spaceAvail = store.AvailableFreeSpace;
if (spaceReq > spaceAvail)
{
return false;
}
return true;
}
}
If space was available, save as image to IsolatedStorage using the below function:
private void SaveToJpeg(Stream stream)
{
using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isostream = iso.CreateFile("image1.jpg"))
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, isostream, wb.PixelWidth, wb.PixelHeight, 0, 85);
isostream.Close();
LoadImageFromIsolatedStorage(); //Load recently saved image into the image control
}
}
}
Load the image in image control from IsolatedStorage:
private void LoadImageFromIsolatedStorage()
{
byte[] data;
try
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = isf.OpenFile("image1.jpg", FileMode.Open, FileAccess.Read))
{
data = new byte[isfs.Length];
isfs.Read(data, 0, data.Length);
isfs.Close();
}
}
MemoryStream ms = new MemoryStream(data);
BitmapImage bi = new BitmapImage();
bi.SetSource(ms);
imageControl1.Source = bi;
}
catch
{
}
}
Image taken randomly from Google Search. Credits to the image lie to the owner.
Hope this helps. :)
@Mark , you are correct, this works according to what you suggest.
i think the problem is if i used code below, i got the byte array is byte[1227]
var requestMessage = new HttpRequestMessage(HttpMethod.Get, ImageName);
var responseMessage = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
var responseData = await responseMessage.Content.ReadAsByteArrayAsync();
return responseData;
and if i use var byteArray = await client.GetByteArrayAsync(ImageName);
the byte array size is byte[5996]
i do not know why this happens, but Mark's solution works.
all my code is as below:
in a MVVM pattern
// get image from URL, ImageName is an absolute Url
public static async Task<BitmapImage> GetWebImageByImageName(string ImageName)
{
//Uri imageServerUril = new Uri(ImageName);
var byteArray = await client.GetByteArrayAsync(ImageName);
//Convert byte array to BitmapImage
BitmapImage bitmapImage;
using (MemoryStream ms = new MemoryStream(byteArray))
{
bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
}
return bitmapImage;
}
in the ViewModel
public void LoadPage(int pageNumber)
{
if (pageNumber == 1)
{
this.ArticleCollection.Clear();
}
IsLoading = true;
ReadArticleList(pageNumber);
}
private async void ReadArticleList(int pageNumber)
{
try
{
List<Article> articleList = new List<Article>();
articleList = await CollectionHttpClient.GetArticlesByPageAsync(pageNumber);
foreach (var item in articleList)
{
item.BitImage = await CollectionHttpClient.GetWebImageByImageName(item.ImagePathList[0]);
this.ArticleCollection.Add(item);
}
IsLoading = false;
}
catch(Exception ex)
{
if (ex.HResult == -2146233088 && ex.Message.Equals("Response status code does not indicate success: 404 ()."))
{
MessageBox.Show("The network is not set right. Internet cannot be accessed.");
}
else
{
MessageBox.Show("sorry, no data.");
}
IsLoading = false;
}
}
Model is:
public class Article : INotifyPropertyChanged
{
private long _Id;
public long ID
{
get { return _Id; }
set
{
if (_Id != value)
{
_Id = value;
NotifyPropertyChanged("ID");
}
}
}
private string _subject;
public string Subject
{
get
{
return _subject;
}
set
{
if (_subject != value)
{
_subject = value;
NotifyPropertyChanged("Subject");
}
}
}
private string _words;
public string Words
{
get
{
return _words;
}
set
{
if (_words != value)
{
_words = value;
NotifyPropertyChanged("Words");
}
}
}
private DateTime _publishDate;
public DateTime PublishDate
{
get
{ return _publishDate; }
set
{
if (_publishDate != value)
{
_publishDate = value;
NotifyPropertyChanged("PublishDate");
}
}
}
private ObservableCollection<string> _imagePathList = new ObservableCollection<string>();
public ObservableCollection<string> ImagePathList
{
get { return this._imagePathList; }
set
{
if (this._imagePathList != value)
{
this._imagePathList = value;
// I'm going to assume you have the NotifyPropertyChanged
// method defined on the view-model
this.NotifyPropertyChanged();
}
}
}
BitmapImage _image;
public BitmapImage BitImage
{
get
{
return _image;
}
set
{
if (ImagePathList.Any())
{
value = new BitmapImage(new Uri(ImagePathList.FirstOrDefault(), UriKind.RelativeOrAbsolute));
_image = value;
}
}
}
private Uri _firstImage;
public Uri FirstImage
{
get
{
return _firstImage;
}
set
{
if (_firstImage != value)
{
_firstImage = value;
NotifyPropertyChanged("FirstImage");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
First if you have the url you can give url to the binding paramter and it will automatically show the image or if you want to download the image and save it & then display it so here is the code for byte to image & image to byte.
{
BitmapImage image = new BitmapImage();
MemoryStream ms = new MemoryStream();
WriteableBitmap wb = new WriteableBitmap(image);
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
imageBytes = ms.ToArray();
}
Use this to save image because i am using it my code.
User contributions licensed under CC BY-SA 3.0