繁体   English   中英

如何以Skiasharp Xamarin形式两次调用PaintSurface

[英]How to call PaintSurface twice in skiasharp xamarin forms

我正在做一个项目,可以更改图像的过滤器。 我正在使用skiasharp更改图像的过滤器。 就像CamScanner Application一样。 但是,当我先将滤镜更改为灰度,然后将其变亮,然后将其更改为棕褐色,然后再次恢复为灰度时,我点击保存,便得到了棕褐色的图像。 我知道最后生成的数据是棕褐色的数据,因此它将保存该数据。 但是,如果我想更改3次以上,则无法正常工作。 请帮帮我。 这是我的编码。

  <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
                 BackgroundColor="Black"
                 x:Class="JC.EditPage">
        <ContentPage.Content>

            <StackLayout Padding="10,10,10,10" Orientation="Vertical">


                <Image x:Name="imageView" HeightRequest="450"
                       HorizontalOptions="FillAndExpand"
                       VerticalOptions="CenterAndExpand" IsVisible="True"/>

                <StackLayout x:Name="canvasStackView" IsVisible="False">
                    <skia:SKCanvasView HeightRequest="450" PaintSurface="OnCanvasViewPaintSurface" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"/>
                </StackLayout>

                <StackLayout x:Name="canvasLightenStackView" IsVisible="False">
                    <skia:SKCanvasView HeightRequest="450" PaintSurface="OnCanvasViewPaintSurfaceLighten" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"/>
                </StackLayout>

                <StackLayout x:Name="canvasSepiaStackView" IsVisible="False">
                    <skia:SKCanvasView HeightRequest="450" PaintSurface="OnCanvasViewPaintSurfaceSepia" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"/>
                </StackLayout>

      <ScrollView Orientation="Horizontal" HorizontalScrollBarVisibility="Never">
                    <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand" x:Name="filterStack" IsVisible="True">
                        <StackLayout WidthRequest="100" HeightRequest="70" BackgroundColor="White">
                            <Label Text="Original" FontFamily="Bold" Font="14" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Tapped="Original_Tapped">
                                </TapGestureRecognizer>
                            </StackLayout.GestureRecognizers>
                        </StackLayout>

                        <StackLayout WidthRequest="100" HeightRequest="70" BackgroundColor="White" >
                            <Label Text="Grayscale" FontFamily="Bold" Font="14" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Tapped="Grayscale_Tapped">
                                </TapGestureRecognizer>
                            </StackLayout.GestureRecognizers>
                        </StackLayout>

                        <StackLayout WidthRequest="100" HeightRequest="70" BackgroundColor="White">
                            <Label Text="Lighten" FontFamily="Bold" Font="14" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Tapped="Lighten_Tapped">
                                </TapGestureRecognizer>
                            </StackLayout.GestureRecognizers>
                        </StackLayout>

                        <StackLayout WidthRequest="100" HeightRequest="70" BackgroundColor="White" >
                            <Label Text="Sepia" FontFamily="Bold" Font="14" TextColor="Black" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Tapped="Speia_Tapped">
                                </TapGestureRecognizer>
                            </StackLayout.GestureRecognizers>
                        </StackLayout>
                    </StackLayout>
                </ScrollView>

                <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand" BackgroundColor="White">
                    <Image Source="goback.png" HorizontalOptions="StartAndExpand">
                        <Image.GestureRecognizers>
                            <TapGestureRecognizer Tapped="goback_Tapped"/>
                        </Image.GestureRecognizers>
                    </Image>

                    <Image Source="tick.png" HorizontalOptions="EndAndExpand">
                        <Image.GestureRecognizers>
                            <TapGestureRecognizer Tapped="Save_Tapped"/>
                        </Image.GestureRecognizers>
                    </Image>
                </StackLayout>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

这是我的XAML.CS文件-

  private async void Grayscale_Tapped(object sender, EventArgs e)
    {
        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");



        adjust = false;
        canvasEditStackView.IsVisible = false;
        canvasSepiaStackView.IsVisible = false;
        canvasLightenStackView.IsVisible = false;
        imageView.IsVisible = false;
        canvasStackView.IsVisible = true;
        filterStack.IsVisible = true;
        original = false;

        byte[] tempArray = await StorageHelper.LoadImage(image, path);

       canvasView = new SKCanvasView();
       canvasView.PaintSurface += OnCanvasViewPaintSurface;

        using (Stream stream = new MemoryStream(tempArray))
        {
            if (stream != null)
            {
                libraryBitmap = SKBitmap.Decode(stream);
                canvasView.InvalidateSurface();
            }
        }
        DependencyService.Get<IProgressInterface>().DismissLoader();
    }

    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        Console.WriteLine("Hits");
        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");

        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        using (SKPaint paint = new SKPaint())
        {

            paint.ColorFilter =
                SKColorFilter.CreateColorMatrix(new float[]
                {
                0.21f, 0.72f, 0.07f, 0, 0,
                0.21f, 0.72f, 0.07f, 0, 0,
                0.21f, 0.72f, 0.07f, 0, 0,
                0,     0,     0,     1, 0
                });

            canvas.DrawBitmap(libraryBitmap, info.Rect, BitmapStretch.Uniform, paint: paint);
            DependencyService.Get<IProgressInterface>().DismissLoader();
        }
        var snap = surface.Snapshot();
        SKData data = snap.Encode();
        saveData = data;

    }

    private async void Lighten_Tapped(object sender, EventArgs e)
    {
        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");


        adjust = false;
        imageView.IsVisible = false;
        canvasEditStackView.IsVisible = false;
        canvasStackView.IsVisible = false;
        canvasSepiaStackView.IsVisible = false;
        canvasLightenStackView.IsVisible = true;
        filterStack.IsVisible = true;
        original = false;

        byte[] tempArray = await StorageHelper.LoadImage(image, path);

        canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurfaceLighten;

        using (Stream stream = new MemoryStream(tempArray))
        {
            if (stream != null)
            {
                libraryBitmap = SKBitmap.Decode(stream);
                canvasView.InvalidateSurface();
            }
        }
        DependencyService.Get<IProgressInterface>().DismissLoader();

    }

    void OnCanvasViewPaintSurfaceLighten(object sender, SKPaintSurfaceEventArgs args)
    {
        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        using (SKPaint paint = new SKPaint())
        {
            paint.ColorFilter =
                SKColorFilter.CreateColorMatrix(new float[]
                {
                0.75f, 0.25f, 0.25f, 0, 0,
                0.25f, 0.75f, 0.25f, 0, 0,
                0.25f, 0.25f, 0.75f, 0, 0,
                0, 0, 0, 1, 0
                });
            canvas.DrawBitmap(libraryBitmap, info.Rect, BitmapStretch.Uniform, paint: paint);
            DependencyService.Get<IProgressInterface>().DismissLoader();
        }
        var snap = surface.Snapshot();
        SKData data = snap.Encode();
        saveData = data;

    }

    public async void Speia_Tapped(object sender, EventArgs e)
    {

        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");



        adjust = false;
        imageView.IsVisible = false;
        canvasEditStackView.IsVisible = false;
        canvasStackView.IsVisible = false;
        canvasLightenStackView.IsVisible = false;
        canvasSepiaStackView.IsVisible = true;
        filterStack.IsVisible = true;
        original = false;

        byte[] tempArray = await StorageHelper.LoadImage(image, path);

        canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurfaceSepia;

        using (Stream stream = new MemoryStream(tempArray))
        {
            if (stream != null)
            {
                libraryBitmap = SKBitmap.Decode(stream);
                canvasView.InvalidateSurface();

            }
        }
        DependencyService.Get<IProgressInterface>().DismissLoader();
    }

    void OnCanvasViewPaintSurfaceSepia(object sender, SKPaintSurfaceEventArgs args)
    {
        DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();
        using (SKPaint paint = new SKPaint())
        {
            paint.ColorFilter =
                SKColorFilter.CreateColorMatrix(new float[]
                {
                  1, 0,   0, 0, 0,
                  0, 1,   0, 0, 0,
                  0, 0, 0.8f, 0, 0,
                  0, 0,   0, 1, 0
                });
            canvas.DrawBitmap(libraryBitmap, info.Rect, BitmapStretch.Uniform, paint: paint);
            DependencyService.Get<IProgressInterface>().DismissLoader();
        }
        var snap = surface.Snapshot();
        SKData data = snap.Encode();
        saveData = data;
    }

这是我的保存命令。

 if (original == true)
            {
                var editPref = DependencyService.Get<IUserPreferences>();
                editPref.SaveString("edit", "false");

                await Navigation.PushModalAsync(new desiredLocationStoragePage(path));
            }
            else
            {
                var editPref = DependencyService.Get<IUserPreferences>();
                editPref.SaveString("edit", "true");
                string saveName = fileName;
                using (var stream = File.OpenWrite(saveName))
                {
                    saveData.SaveTo(stream);
                }
                await Navigation.PushModalAsync(new desiredLocationStoragePage(fileName));

            }



   please help me out guys I am quite stuck after this phase

我希望我做对了,您正在使用几个SKCanvasViews,并根据用户在应用程序中选择的“模式”,激活相应的表面吗?

我不建议这样做。 即使〜kinda〜有效,它也可能很快变得令人困惑。

我对您的问题的处理方法是通过以下方式重写视图:

创建一个包含过滤器名称和“ none”的另一个条目的枚举,例如

public enum Filters
{
    None = 0,
    Grayscale = 1,
    Lighten = 2,
    Sepia = 4
} 

然后在页面中创建此枚举类型的属性。

Filters currentFilter = Filters.None;

现在,您无需将渲染代码复制4次,而可以将主要PaintSurface方法更改为:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    Console.WriteLine("Hits");
    DependencyService.Get<IProgressInterface>().ShowLoader("Please wait...");

    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();



    using (SKPaint paint = new SKPaint())
    {
        // check if currentFilter is set to Filters.None
        if( (currentFilter & Filters.None) == Filters.None )
        {
            paint.ColorFilter =
                SKColorFilter.CreateColorMatrix(new float[]
                {
                    0.21f, 0.72f, 0.07f, 0, 0,
                    0.21f, 0.72f, 0.07f, 0, 0,
                    0.21f, 0.72f, 0.07f, 0, 0,
                    0,     0,     0,     1, 0
                });
        }
        // check if currentFilter is set to Filters.Lighten
        else if ( (currentFilter & Filters.Lighten) == Filters.Lighten)
        {
            paint.ColorFilter =
                SKColorFilter.CreateColorMatrix(new float[]
                {
                    0.75f, 0.25f, 0.25f, 0, 0,
                    0.25f, 0.75f, 0.25f, 0, 0,
                    0.25f, 0.25f, 0.75f, 0, 0,
                    0, 0, 0, 1, 0
            });
        }

        /*
            ... proceed with other filters accordingly ....
        */

        canvas.DrawBitmap(libraryBitmap, info.Rect, BitmapStretch.Uniform, paint: paint);
        DependencyService.Get<IProgressInterface>().DismissLoader();
    }
    var snap = surface.Snapshot();
    SKData data = snap.Encode();
    saveData = data;

}

因此,在点击SetFilterButton时,您要做的就是将页面的customFilter属性设置为相应的过滤器并调用

canvasView.InvalidateSurface();

因此将重绘表面,然后保存图像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM