【问题标题】:Load a image from web URL in WP8在 WP8 中从 Web URL 加载图像
【发布时间】:2014-02-18 06:21:33
【问题描述】:

我有一张指定网址的网页图片,可以在浏览器中浏览。

我试图从 web url 中检索它,当程序转到 bitmapImage.SetSource(ms); 时,我得到一个异常“

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...

" 我确实在stackoverflow上搜索了其他问题......但对此没有帮助。谁能帮帮我?

byte数组确实有数据,在运行时调试,返回imageByteArray = {byte[1227]};我的选择是将字节数组转换为 BitmapImage 时发生异常。

在 httpclient 包装类中:

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;

        }

在视图模型中:

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;
            }

        }

* 详细信息 *

  1. BitImage 是 BitmapImage 的一个实例;
  2. item.BitImage:item 是 Article 的一个实例
  3. 图片格式为JPEG

文章型号如下:

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));
            }
        }
    }

【问题讨论】:

  • 第一个问题,为什么不设置 Image.Source = "http://...image.jpg"?您是否也尝试过将图像下载为 Stream 而不是 byte[]?
  • 我测试了您的代码,它适用于我使用的测试图像(包括 jpeg)。设置URI的时候可以显示图片吗?您仍然可以做的一件事是使用 HttpClient 中的 GetByteArrayAsync 方法,因为这将消除转换回复的需要。
  • @Martin Suchan,我不确定,Image.Source 是异步还是同步,所以我决定自己异步获取网络图像;我尝试将图像下载为 byte[],然后我需要将其转换为 BitmapImage,Stream 只是 byte[] 和 BitmapImage 之间的一个临时。
  • @Mark,GetByteArrayAsync 确实有效,我以前用过这个,但它对我来说不稳定,我不知道为什么,它工作过一次,然后它失败并出现异常“响应状态代码确实不表示成功:406(不可接受)。”。我没有做任何改变。
  • @max 我建议您使用 fiddler 之类的工具监控流量。我认为您的客户端和服务器之间的通信有些奇怪。 406表示接收到的内容无效/客户端无法处理..您是否尝试使用不同的图像/服务器?

标签: c# windows-phone-7 windows-phone-8 bitmapimage dotnet-httpclient


【解决方案1】:

如果您只想显示来自远程服务器的图像而不保存它,请执行以下操作:

imageControl1.Source = new BitmapImage(new Uri("http://delisle.saskatooncatholic.ca/sites/delisle.saskatooncatholic.ca/files/sample-1.jpg", UriKind.Absolute));

如果您想将图像保存到 IsolatedStorage,您可以执行以下操作:

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);
        }
    }

检查IsolatedStorage空间是否可用的功能,否则将不会下载图像。

    private bool IsSpaceIsAvailable(long spaceReq)
    {
        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
        {
            long spaceAvail = store.AvailableFreeSpace;
            if (spaceReq > spaceAvail)
            {
                return false;
            }
            return true;
        }
    }

如果空间可用,请使用以下函数将图像另存为 IsolatedStorage:

    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
            }
        }
    }

从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
        {
        }
    }

从 Google 搜索中随机获取的图像。图片版权归所有者所有。

希望这会有所帮助。 :)

【讨论】:

    【解决方案2】:

    @Mark,你是对的,这按照你的建议工作。

    我认为问题是如果我使用下面的代码,我得到的字节数组是 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;
    

    如果我使用var byteArray = await client.GetByteArrayAsync(ImageName);,则字节数组大小为字节[5996]

    我不知道为什么会这样,但 Mark 的解决方案有效。

    我的所有代码如下:

    在 MVVM 模式中

            // 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;
    
    
            }
    

    在视图模型中

    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;
                }
    
            }
    

    型号是:

    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));
                }
            }
        }
    

    【讨论】:

      【解决方案3】:

      首先,如果您有 url,您可以将 url 提供给绑定参数,它会自动显示图像,或者如果您想下载图像并保存并显示它,那么这里是字节到图像和图像的代码字节。

          {
              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();
          }
      

      使用它来保存图像,因为我正在使用它作为我的代码。

      【讨论】:

      • 你在哪里找到了 FromStream 方法,你确定它在 WP8 中吗?
      猜你喜欢
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      相关资源
      最近更新 更多