2

WinRT 프로젝트에서 WriteableBitmapEx를 사용하고 있습니다. 사용자 그림 라이브러리에서 WriteableBitmap에 이미지를로드합니다. 그러나 그 이미지에 즉시 쓸 수는 없습니다. 이미지 자체로 덮어 쓰게됩니다. (이미지를 비동기 적으로로드 한 다음 그 위에 내 그림을 덮어 쓰는 것처럼 보입니다.) 나는 그것을하지 못하게하는 방법을 모른다. (나는 SetSource에서 Await을 사용해 보았지만 Async 메서드는 아니다.)WinRT에서 이미지를로드 한 다음 이미지를로드하기 전에 이미지를로드하는 데 필요한만큼 기다리는 방법은 무엇입니까?

나는 "Await Task.Delay (1000)"을 사용했는데 작동하지만 1000ms가 충분하지 않을 수도 있기 때문에 해킹이되는 것처럼 보입니다. 진행하기 전에 비트 맵이로드 될 때까지 기다려주세요. .

누구나 내가 뭘 잘못하고있는 것 같아 보이거나 처리를하기 전에 WriteableBitmap이 그림 라이브러리에서로드되도록 할 수 있습니까? 여기에 내가 만든 예제 코드는 다음과 같습니다

Dim file = Await picker.PickSingleFileAsync 

If file Is Nothing Then 
    Exit Sub 
End If 

Dim wbm As New WriteableBitmap(1, 1) 
wbm.SetSource(Await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) 

' If I don't have this, the DrawLine will not show up, if I do, it will. 
Await Task.Delay(1000) 

wbm.DrawLine(1, 1, 255, 255, Colors.Green) 
wbm.Invalidate() 

ImageMain.Source = wbm 
+0

이 프로젝트를 사용하고 있습니까? http://writeablebitmapex.codeplex.com/ –

+0

내 WinRT 버전이라고 생각합니다. http://bit.ly/WriteableBitmapExWinRT –

+0

필립 (Filip)의 WinRT 포트를 사용하고 있습니다. 제도법. Btw, Filip에게 감사드립니다. :)이 모든 것을 배우고 나면 소스 코드를 게시 할 것입니다. –

답변

2

OpenAsync 반환은 스트림 데이터가 실제로에서 읽어하지 않는 것이 가능한 것을 의미한다. 그러므로 당신이 먼저 오픈 + 읽기를 원할 것입니다. 그리고 나서 당신은 괜찮을 것입니다.

필자는 ReadAsync에서 먼저 버퍼를 만들고 전달해야한다고 지적했기 때문에 OpenreadAsync를 수행하여 IRandomAccessStream을 얻은 후 DataReader을 사용하여 바이트 배열에 실제로 스트림을로드하기 위해 아래 스 니펫을 업데이트했습니다.

var randomAccessStream = await file.OpenReadAsync(); 

var dataReader = new DataReader(randomAccessStream); 
await dataReader.LoadAsync(randomAccessStream.Size); 

byte[] imageBytes; 
dataReader.ReadBytes(out imageBytes); 

wbm.SetSource(new MemoryStream(imageBytes)); 
+0

피드백을 주신 James에게 피드백을 주셔서 감사드립니다. –

+0

흥미 롭지 만, 파일 스트림에서 읽고 내용을 MemoryStream으로 제공하면 왜 차이가 있습니까? 스트림을 읽어야하는 WriteableBitmap입니다. 스트림의 유형에 상관없이 보이지는 않습니다. 접근 방식의 이점은 파일 스트림을 닫아도 WB가 내용을 표시하기 전에 파일을 삭제할 수 있다는 것입니다. –

+0

@FilipSkakun - 실제로 스트림을 제공하고 싶지 않습니다. 원래 SetSource (imageBytes)를 사용하여 스 니펫을 게시 한 다음 해당 오버로드가 없음을 알았습니다. 아마도 바이트 배열에서 WritableBitmap을 생성하는 방법이있을 것입니다. 아마도 Image.Create를 사용할 수 없습니까? 확실하지는 않지만 실제로 스트림을 사용하고 싶지는 않을 것입니다.MemoryStream을 사용하는 것은 실제로 SetSource가 나중의 DrawLine 전에 수행 될 MemoryStream과 충분히 빠르고/또는 동기화 될 구현 세부 사항에 의존합니다. –

1

WB에는 BitmapImage가 열리기를 기다리는 이벤트가 없다고 생각합니다. BitmapDecoder/CreateAsync/GetPixelDataAsync/DetachPixelData를 사용하고 wb.SetSource()를 호출하는 대신 WB의 픽셀 버퍼에 결과 바이트 배열을 복사하려고합니다. 그런 다음 wb.Invalidate()를 호출 할 수 있습니다. 또는 지연 호출을 무효화로 대체하십시오.

+0

두 가지 모두 시도해 보겠습니다. 다시 한 번 감사드립니다. 필립이 나를 이해하고 배우도록 도와주었습니다. 대단히 감사합니다. –

8

이 메서드는 응용 프로그램의 콘텐츠에서 이미지를로드하고 디코드 한 다음 바로 사용할 수있는 WriteableBitmap을 전달합니다. 는 WriteableBitmapEx library에서 촬영 :

/// <summary> 
/// Loads an image from the applications content and fills this WriteableBitmap with it. 
/// </summary> 
/// <param name="bmp">The WriteableBitmap.</param> 
/// <param name="uri">The URI to the content file.</param> 
/// <returns>The WriteableBitmap that was passed as parameter.</returns> 
public static async Task<WriteableBitmap> FromContent(this WriteableBitmap bmp, Uri uri) 
{ 
    // Decode pixel data 
    var file = await StorageFile.GetFileFromApplicationUriAsync(uri); 
    var decoder = await BitmapDecoder.CreateAsync(await file.OpenAsync(FileAccessMode.Read)); 
    var transform = new global::Windows.Graphics.Imaging.BitmapTransform(); 
    var pixelData = await decoder.GetPixelDataAsync(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb); 
    var pixels = pixelData.DetachPixelData(); 

    // Copy to WriteableBitmap 
    bmp = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); 
    using (var bmpStream = bmp.PixelBuffer.AsStream()) 
    { 
     bmpStream.Seek(0, SeekOrigin.Begin); 
     bmpStream.Write(pixels, 0, (int)bmpStream.Length); 
     return bmp; 
    } 
} 

BTW, WinRT는 이제 공식적으로 WriteableBitmapEx에 의해 지원됩니다. ;) http://kodierer.blogspot.de/2012/05/one-bitmap-to-rule-them-all.html

+0

+1하지만이 해결 방법은 끔찍합니다. WinRT가 출시되기 전에 그들이이 모양을 얻길 바랍니다. –