2012-01-07 54 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