2013-06-16 1 views
0

현재 위대한 WriteableBitmapEx Framework를 사용하여 Windows Store (WinRT) 용 작은 이미지 편집 응용 프로그램을 작성하고 있습니다. .convolute와 같은 함수는 Surface에서 테스트 한 WinRT 장치에서 잠시 시간이 걸릴 수 있으므로 이러한 요청을 비동기 적으로 만들어 UI가 차단되지 않도록하고 진행률 링을 표시 할 수 있습니다.WriteableBitmapEx를 사용한 비동기 이미지 편집

이것은 지금까지 시도한 것으로 코드 자체가 작동합니다. 그러나 UI는 여전히 차단되고 링은 표시되지 않습니다. 코드를 실행하는 데 약 2 초가 걸립니다. 나는 그것을하지 않는 방법에 async을 추가 언급 한 바와 같이

// Start Image editing when selection is changed 
private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     progressRing.IsActive = true; 

     try 
     { 
      filteredImage = await FilterMethod.imageBW(originalImage, filteredImage); 

     } 
     catch 
     { 
      Debug.WriteLine("No items selected"); 
     } 

     mainImage.Source = filteredImage; 
     progressRing.IsActive = false; 
    } 


    // Black & White 
    public static async Task<WriteableBitmap> imageBW(WriteableBitmap originalImage, WriteableBitmap filteredImage) 
    { 
     filteredImage = originalImage.Clone(); 

     using (filteredImage.GetBitmapContext()) 
     { 
      filteredImage.ForEach(ImageEdit.toGrayscale); 
     } 

     return filteredImage; 
    } 


    // Grayscale 
    public static Color toGrayscale(int x, int y, Color color) 
    { 
     byte gray = (byte)(color.R * .3f + color.G * .59f + color.B * .11f); 
     Color newColor = Color.FromArgb(255, gray, gray, gray); 
     return newColor; 
    } 
+0

당신은 리, 방법에'async'를 추가하면 자동적으로 백그라운드에서 일을 실행하여 비동기하지 않는 것을 알고 같습니다

await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => {} 

블록은, 그래서 지금은 다음과 같습니다 응? 그리고 당신은 어떤 것도 기다리고 있지 않습니다 ... –

+0

죄송합니다, 코드를 복사하는 것을 기다리고 있습니다. 백그라운드에서 어떻게 실행합니까? – Thomas

+0

가장 쉬운 방법은'Task'에서 이미지를 회색조로 변환하는 전체 메서드를 래핑하여 백그라운드에서 실행하고 결과를 '대기'하는 것입니다. –

답변

1

이미지 편집 이런 종류의 UI 스레드에서 일어날 필요가있는 것 같다, 나는 안에 내 코드를 포장 할 수 있었다

private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    progressRing.IsActive = true; 

    try 
    { 
     await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
     { 
      filteredImage = await FilterMethod.imageBW(originalImage, filteredImage); 
     } 

    } 
    catch 
    { 
     Debug.WriteLine("No items selected"); 
    } 

    mainImage.Source = filteredImage; 
    progressRing.IsActive = false; 
} 
+0

불행하게도 Windows Phone에서는 작동하지 않습니다. 어떤 아이디어? –

1

OK, 자동적으로 비동기 방식으로 일을. 이것은 컴파일러가 스테이트 머신으로 변환하여 연속 쓰기를 더 쉽게 만들어 준다는 것을 의미합니다.

백그라운드에서 처리하는 가장 쉬운 방법은 계산을 Task에 랩핑하는 것입니다. 내가 스레드 간 마샬링 비록 비트 맵과 같은 방법을 아주 확실하지 않다 :

private async void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     progressRing.IsActive = true; 

     try 
     { 
      var filteredImage = await Task.Run(() => 
          { 
           var clonedBitmap = originalImage.Clone(); 

           using (clonedBitmap.GetBitmapContext()) 
           { 
            clonedBitmap.ForEach(ImageEdit.toGrayscale); 
           } 

           return clonedBitmap; 
          }); 

      mainImage.Source = filteredImage; 
     } 
     catch 
     { 
      Debug.WriteLine("No items selected"); 
     }  

     progressRing.IsActive = false; 
    } 
+0

thx. 불행히도 그 코드를 실행하려고하면 다음 오류가 발생합니다. "응용 프로그램이 다른 스레드에 대해 마샬링 된 인터페이스를 호출했습니다" 내가 읽은 바로는 UI 스레드가 그런 종류의 이미지 조작을 수행해야합니다. 지금 Window.Current.Dispatcher.RunAsync를 사용하여 작업하고 있습니다. – Thomas

+1

@Thomas Yep, 그게 전부입니다. 그게 내가 '크로스 스레드 마샬링이 어떻게 비트 맵처럼 보이는지 모르겠다'라고 말한 것입니다. –