2012-01-07 3 views
0

Редактировать: Для тех, кому нужно разбить изображение (то есть скопировать часть WriteableBitmap в другое), вы можете использовать Buffer.BlockCopy и использовать пиксели WriteableBitmaps ' [] в качестве аргумента.Windows Phone 7.1: Split byte [] image and convert to BitmapImage

Я задал этот вопрос, прежде чем: Image won't load completely on Windows Phone 7.5

я работал над этим вопросом в течение нескольких часов, и я попробовал несколько вещей. Я не знаком с типами изображений и т. Д., Поэтому вполне возможно, что мне не хватает базовой теории (например, я не могу разбить изображение байта [] и преобразовать их в BitmapImage).

То, что я пытаюсь сделать, это:

  1. Загрузить изображение (JPEG) с Web с помощью WebClient.
  2. Декодирование JPEG из потока, который WebClient вернулся ко мне с помощью PictureDecoder.DecodeJpeg и получить объект WriteableBitmap
  3. Преобразование WriteableBitmap.Pixels массив из ИНТ [] в байт []
  4. расколоть байт [] массив в несколько штук, поэтому они не превысят ограничение размера 2000x2000
  5. Преобразование каждой части в BitmapImage, чтобы я мог использовать их в своем приложении WP7.1 Silverlight.

Но я получаю System.Exception с Неизвестной ошибкой в ​​System.Windows.dll в этих строках:

firstImg.SetSource(ms); 

newImg.SetSource(ms2); 

BTW, 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. Вы также можете создать новую WriteableBitmap из копий разделов большего изображения, используя функцию blitting.

+0

У меня все же есть то же исключение. – mostruash

+0

Может зайти в библиотеку WriteableBitmapEx. – keyboardP

+0

Спасибо. WriteableBitmapEx может копировать пиксели из одного WriteableBitmap в другой. Точно подходит для моих нужд. – mostruash