2013-06-14 35 views
15

Tôi đang làm việc trên ứng dụng Windows 8 Metro áp dụng bộ lọc cho hình ảnh. Tôi có một phiên bản web của ứng dụng và muốn chuyển nó. Nhưng như chúng ta đều biết WinRT không có tất cả những điều tốt đẹp. NET cung cấp cách khác:/C# Windows 8 Store (Metro, WinRT) mảng Byte tới BitmapImage

Hiện tại tôi đang áp dụng bộ lọc trên mảng byte và tôi muốn giữ nó theo cách đó, vì nó siêu nhanh! Vì vậy, trong vài ngày qua, tôi đã tìm kiếm các cách để chuyển đổi một StorageFile thành byte [] và sau đó là byte [] thành BitmapImage.

Cho đến giờ tôi đã thực hiện thao tác đầu tiên (StorageFile thành byte []). Đây là cách tôi làm điều đó:

public async Task<Byte[]> ImageFileToByteArray(StorageFile file) 
    { 
     IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 
     BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 
     PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); 
     return pixelData.DetachPixelData(); 
    } 

Đoạn mã này trả về một byte[] chứa dữ liệu pixel là BGRA.

Và đây là phần khó khăn. Tôi không thể chuyển đổi thành công mảng byte thành bitmapImage. Tôi đã tìm kiếm trên tất cả các nơi và nhiều người đề nghị sử dụng WriteableBitmap nhưng điều đó không làm tốt cho tôi nhiều. Tôi cũng đã tìm thấy một số đoạn mã nên hoạt động ... nhưng chúng không.

Một trong những giải pháp tôi đã cố gắng sử dụng InMemoryRandomAccessStream như thế này:

public async Task<BitmapImage> ByteArrayToBitmapImage(Byte[] pixels) 
    { 
     var stream = new InMemoryRandomAccessStream(); 
     await stream.WriteAsync(pixels.AsBuffer()); 
     stream.Seek(0); 
     var image = new BitmapImage(); 
     await image.SetSourceAsync(stream); 
     return image; 
    } 

Cái này ném ngoại lệ sau đây:

Một ngoại lệ của loại 'System.Exception' xảy ra trong mscorlib. dll nhưng không được xử lý trong mã người dùng

Thông tin bổ sung: Không tìm thấy thành phần. (Ngoại lệ từ HRESULT: 0x88982F50)

tôi đã cố gắng sử dụng dòng này thay vì:

PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
      BitmapPixelFormat.Bgra8, 
      BitmapAlphaMode.Ignore, 
      new BitmapTransform(), 
      ExifOrientationMode.IgnoreExifOrientation, 
      ColorManagementMode.DoNotColorManage); 

Nhưng nó đã làm cho tôi không tốt kể từ khi tôi tiếp tục nhận ngoại lệ đó.

Tôi cũng đã cố gắng này:

var bitmapImage = new BitmapImage(); 
     var pixels = await ImageFileToByteArray(file); 
     ImageSource imgSource; 
     using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream()) 
     { 
      using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0))) 
      { 
       writer.WriteBytes(pixels); 
       await writer.StoreAsync(); 
      } 

      await bitmapImage.SetSourceAsync(ms); 
      imgSource = bitmapImage; 
     } 

Và có được ngoại lệ tương tự như phần đầu tiên của mã.

Tôi cũng đã thử một số cách khác bao gồm sử dụng Luồng bình thường rồi chuyển đổi thành IRandomAccessStream nhưng chúng cũng không hoạt động.

Tất cả các mã trên có vẻ tốt với tôi. Vì vậy, tôi đoán tại thời điểm này là vấn đề là trong byte[]. Tôi đoán rằng định dạng của pixelData bên trong không hợp lệ, vì vậy tôi đã thử thay đổi nó thành RGBA nhưng điều đó cũng không giúp được gì. Ngoài ra PixelHeight và PixelWidth của BitmapImage là 0.

+0

Bạn đã tìm thấy giải pháp cho điều này chưa? Tôi cũng gặp vấn đề tương tự. – TheQuestioner

Trả lời

12

này đang làm việc cho tôi,

private async Task<BitmapImage> ByteArrayToBitmapImage(byte[] byteArray) 
    { 
     var bitmapImage = new BitmapImage(); 

     var stream = new InMemoryRandomAccessStream(); 
     await stream.WriteAsync(byteArray.AsBuffer()); 
     stream.Seek(0); 

     bitmapImage.SetSource(stream); 
     return bitmapImage; 
    } 
+0

đã phải tìm kiếm không (stream.Seek (0)) để làm việc :) cảm ơn rất nhiều :) –

1

đây là answer..hope đầu tiên của tôi nó sẽ giúp.

Tôi đã gặp vấn đề tương tự và tôi đã bỏ ra nhiều hơn rồi 6 giờ để tìm ra điều này. đây là những gì tôi đã đưa ra: những gì bạn nói là đúng.có 2 waye để chuyển đổi hình ảnh để ByteArray:

Đầu tiên aproach (của bạn)

 public async Task<byte[]> ImageFileToByteArrayAsync(StorageFile file) 
    { 
     IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 
     BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); 
     PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); 
     return pixelData.DetachPixelData(); 
    } 

Second aproach

 public async Task<byte[]> ImageFileToByteArrayAsync(StorageFile file) 
    { 
     var inputStream = await file.OpenSequentialReadAsync(); 
     var readStream = inputStream.AsStreamForRead(); 
     var buffer = new byte[readStream.Length]; 
     await readStream.ReadAsync(buffer, 0, buffer.Length); 
     return buffer; 
    } 

nếu bạn sẽ sử dụng aproach thứ hai để giải mã các pic, không có Pixel, công cụ chuyển đổi này sẽ hoạt động:

public class ByteArrayToImageConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     if (value == null || !(value is byte[])) 
      return null; 

     using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream()) 
     { 
      using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0))) 
      { 
       writer.WriteBytes((byte[])value); 
       writer.StoreAsync().GetResults(); 
      } 
      BitmapImage image = new BitmapImage(); 
      image.SetSource(stream); 
      return image; 
     } 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, string language)                   
    { 
     throw new NotImplementedException(); 
    } 

cho lần đầu tiên bạn cần làm việc với Writeabl eBitmap như bạn đã nói.

Các vấn đề liên quan