使用WriteableBitmapEx进行异步图像编辑

时间:2013-06-16 19:12:50

标签: c# windows-store-apps winrt-async writeablebitmapex

我目前正在使用优秀的WriteableBitmapEx Framework为Windows Store(WinRT)编写一个小型图像编辑应用程序。 像.convolute这样的函数在WinRT设备上需要一段时间(在Surface上测试)我想让这些请求异步,因此UI不会被阻止,我可以显示进度环。

这是我到目前为止所尝试的,代码本身正在运行。但UI仍然被阻止,并且戒指没有显示。代码执行大约需要2秒钟。

// 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;
    }

2 个答案:

答案 0 :(得分:1)

好吧,正如我所提到的,将async添加到方法中并不能使它以异步方式自动执行。它只是意味着编译器会将其转换为状态机,这使得编写continuation变得更容易。

在后台处理它的最简单方法是将计算包装在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;
    }

答案 1 :(得分:1)

由于这种图像编辑似乎需要在UI线程上进行,我能够将我的代码包装在

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

阻止,现在它看起来像这样:

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;
}