2012-01-07 111 views
0

编辑:对于需要对图像进行blit(即将WriteableBitmap的一部分复制到另一个图像)的人,可以使用Buffer.BlockCopy并使用WriteableBitmaps的Pixels int []数组作为参数。Windows Phone 7.1:分割字节[]图像并转换为BitmapImage

我问这个问题之前,我一直对这个问题Image won't load completely on Windows Phone 7.5

了好几个小时了,我已经试过几件事情。我不熟悉图像类型等,所以有可能我缺少一个基本的理论(比如我不能分割一个byte []图像并将它们转换成BitmapImage)。

我试图做的是:

  1. 下载使用Web客户端从网络上图片(JPEG)。
  2. 解码的JPEG从Web客户端使用PictureDecoder.DecodeJpeg,并得到一个WriteableBitmap的对象返回到我流
  3. 从int []为byte []
  4. 斯普利特byte []数组分成几个转换WriteableBitmap.Pixels阵列所以它们不会超过2000x2000的大小限制
  5. 将每一块转换为BitmapImage,以便我可以在我的WP7.1 Silverlight应用程序中使用它们。

但我得到的System.Windows.dll中未指定的错误的System.Exception的那些行:

firstImg.SetSource(ms); 

newImg.SetSource(ms2); 

顺便说一句,我下载的JPEG是一个有效的JPEG,我可以显示它没有试图分裂它。

编辑:我下载的Jpeg宽度小于2000,高度大于2000。

这里是我的代码:

private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
    { 
     WriteableBitmap rawImg = PictureDecoder.DecodeJpeg(e.Result); 
     byte[] arr; 
     int height = rawImg.PixelHeight; 
     int count = 0; 

     if (height < 2000) 
      images.Add(new MyImage(rawImg)); 
     else 
     { 
      arr = ConvertToByte(rawImg); 
      MemoryStream ms = new MemoryStream(); 
      ms.Write(arr, 0, 4 * rawImg.PixelWidth * 2000); 
      count++; 
      BitmapImage firstImg = new BitmapImage(); 
      firstImg.SetSource(ms); 
      images.Add(new MyImage(firstImg)); 

      while (height > 2000) 
      { 
       MemoryStream ms2 = new MemoryStream(); 
       ms2.Write(arr, count*2000, 4 * rawImg.PixelWidth * Math.Min(arr.Length - count*2000, 2000)); 
       count++; 
       height -= 2000; 
       BitmapImage newImg = new BitmapImage(); 
       newImg.SetSource(ms2); 
       images.Add(new MyImage(newImg)); 
      } 
     }  
    } 

private byte[] ConvertToByte(WriteableBitmap wb) 
    { 
     int w = wb.PixelWidth; 
     int h = wb.PixelHeight; 
     int[] p = wb.Pixels; 
     int len = p.Length; 
     byte[] result = new byte[4 * w * h]; 

     for (int i = 0, j = 0; i < len; i++, j += 4) 
     { 
      int color = p[i]; 
      result[j + 0] = (byte)(color >> 24); 
      result[j + 1] = (byte)(color >> 16); 
      result[j + 2] = (byte)(color >> 8); 
      result[j + 3] = (byte)(color); 
     } 

     return result; 
    } 

回答

3

后,你写MemoryStream,位置是先进的。在设置信号源之前,请重置位置。

ms.Position = 0; 

编辑 - 你可以使用WriteableBitmapEx。这是一个非常快速的库,可以执行WriteableBitmaps的字节转换。您还可以使用blitting功能从复制较大图像的各个部分创建新的WriteableBitmap。

+0

我仍然得到相同的例外。 – mostruash 2012-01-07 04:30:20

+0

可以查看WriteableBitmapEx库。 – keyboardP 2012-01-07 04:41:26

+0

谢谢。 WriteableBitmapEx可以将像素从一个WriteableBitmap复制到另一个。完全符合我的需求。 – mostruash 2012-01-07 04:54:09