How to call PaintSurface twice in skiasharp xamarin forms











up vote
0
down vote

favorite












I am doing a project wherein I can change the filter of the image. I am using skiasharp to change the filter of the image. It is like that of CamScanner Application. But when I change the filter to grayscale first and then Lighten and then Sepia and then again back to grayscale I hit save I get Sepia's Image. I understand that the last data being generated is that of sepia's hence it is saving that data. But if I want to change more than 3 times it is not working. Please help me out. Here is my coding.



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


and here is my XAML.CS file for that -



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


and this is my save command.



 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









share|improve this question


























    up vote
    0
    down vote

    favorite












    I am doing a project wherein I can change the filter of the image. I am using skiasharp to change the filter of the image. It is like that of CamScanner Application. But when I change the filter to grayscale first and then Lighten and then Sepia and then again back to grayscale I hit save I get Sepia's Image. I understand that the last data being generated is that of sepia's hence it is saving that data. But if I want to change more than 3 times it is not working. Please help me out. Here is my coding.



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


    and here is my XAML.CS file for that -



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


    and this is my save command.



     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









    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am doing a project wherein I can change the filter of the image. I am using skiasharp to change the filter of the image. It is like that of CamScanner Application. But when I change the filter to grayscale first and then Lighten and then Sepia and then again back to grayscale I hit save I get Sepia's Image. I understand that the last data being generated is that of sepia's hence it is saving that data. But if I want to change more than 3 times it is not working. Please help me out. Here is my coding.



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


      and here is my XAML.CS file for that -



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


      and this is my save command.



       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









      share|improve this question













      I am doing a project wherein I can change the filter of the image. I am using skiasharp to change the filter of the image. It is like that of CamScanner Application. But when I change the filter to grayscale first and then Lighten and then Sepia and then again back to grayscale I hit save I get Sepia's Image. I understand that the last data being generated is that of sepia's hence it is saving that data. But if I want to change more than 3 times it is not working. Please help me out. Here is my coding.



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


      and here is my XAML.CS file for that -



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


      and this is my save command.



       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






      xamarin xamarin.forms xamarin.ios xamarin.android skiasharp






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 9 at 5:13









      Nihal Sekhar

      62




      62
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          I hope I got it right, you are using several SKCanvasViews and depending on what "mode" the user chooses in your app, you activate the corresponding surface?



          I wouldn't recommend that. Even though it ~kinda~ works, it might become confusing very fast.



          My approach to your problem would be to rewrite the view in the following way:



          Create an enum containing the names of your filters and another entry for "none", e.g.



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


          Then create a property of the type of this enum in your page.



          Filters currentFilter = Filters.None;


          Now instead of copying your render code 4 times, you could change the main PaintSurface method to something like:



          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;

          }


          So when tapping your SetFilterButton all you need to do is setting the customFilter Property of your page to the corresponding filter and calling



          canvasView.InvalidateSurface();


          so the surface will be redrawn and then saving the image.






          share|improve this answer























          • Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
            – Nihal Sekhar
            Nov 12 at 4:59










          • I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
            – Nihal Sekhar
            Nov 12 at 7:33












          • After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
            – Markus Michel
            Nov 12 at 7:48






          • 1




            I really do not know how to thank you enough.May god bless you. It works like a beaut.
            – Nihal Sekhar
            Nov 12 at 8:43













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53220214%2fhow-to-call-paintsurface-twice-in-skiasharp-xamarin-forms%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          I hope I got it right, you are using several SKCanvasViews and depending on what "mode" the user chooses in your app, you activate the corresponding surface?



          I wouldn't recommend that. Even though it ~kinda~ works, it might become confusing very fast.



          My approach to your problem would be to rewrite the view in the following way:



          Create an enum containing the names of your filters and another entry for "none", e.g.



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


          Then create a property of the type of this enum in your page.



          Filters currentFilter = Filters.None;


          Now instead of copying your render code 4 times, you could change the main PaintSurface method to something like:



          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;

          }


          So when tapping your SetFilterButton all you need to do is setting the customFilter Property of your page to the corresponding filter and calling



          canvasView.InvalidateSurface();


          so the surface will be redrawn and then saving the image.






          share|improve this answer























          • Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
            – Nihal Sekhar
            Nov 12 at 4:59










          • I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
            – Nihal Sekhar
            Nov 12 at 7:33












          • After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
            – Markus Michel
            Nov 12 at 7:48






          • 1




            I really do not know how to thank you enough.May god bless you. It works like a beaut.
            – Nihal Sekhar
            Nov 12 at 8:43

















          up vote
          0
          down vote



          accepted










          I hope I got it right, you are using several SKCanvasViews and depending on what "mode" the user chooses in your app, you activate the corresponding surface?



          I wouldn't recommend that. Even though it ~kinda~ works, it might become confusing very fast.



          My approach to your problem would be to rewrite the view in the following way:



          Create an enum containing the names of your filters and another entry for "none", e.g.



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


          Then create a property of the type of this enum in your page.



          Filters currentFilter = Filters.None;


          Now instead of copying your render code 4 times, you could change the main PaintSurface method to something like:



          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;

          }


          So when tapping your SetFilterButton all you need to do is setting the customFilter Property of your page to the corresponding filter and calling



          canvasView.InvalidateSurface();


          so the surface will be redrawn and then saving the image.






          share|improve this answer























          • Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
            – Nihal Sekhar
            Nov 12 at 4:59










          • I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
            – Nihal Sekhar
            Nov 12 at 7:33












          • After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
            – Markus Michel
            Nov 12 at 7:48






          • 1




            I really do not know how to thank you enough.May god bless you. It works like a beaut.
            – Nihal Sekhar
            Nov 12 at 8:43















          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          I hope I got it right, you are using several SKCanvasViews and depending on what "mode" the user chooses in your app, you activate the corresponding surface?



          I wouldn't recommend that. Even though it ~kinda~ works, it might become confusing very fast.



          My approach to your problem would be to rewrite the view in the following way:



          Create an enum containing the names of your filters and another entry for "none", e.g.



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


          Then create a property of the type of this enum in your page.



          Filters currentFilter = Filters.None;


          Now instead of copying your render code 4 times, you could change the main PaintSurface method to something like:



          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;

          }


          So when tapping your SetFilterButton all you need to do is setting the customFilter Property of your page to the corresponding filter and calling



          canvasView.InvalidateSurface();


          so the surface will be redrawn and then saving the image.






          share|improve this answer














          I hope I got it right, you are using several SKCanvasViews and depending on what "mode" the user chooses in your app, you activate the corresponding surface?



          I wouldn't recommend that. Even though it ~kinda~ works, it might become confusing very fast.



          My approach to your problem would be to rewrite the view in the following way:



          Create an enum containing the names of your filters and another entry for "none", e.g.



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


          Then create a property of the type of this enum in your page.



          Filters currentFilter = Filters.None;


          Now instead of copying your render code 4 times, you could change the main PaintSurface method to something like:



          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;

          }


          So when tapping your SetFilterButton all you need to do is setting the customFilter Property of your page to the corresponding filter and calling



          canvasView.InvalidateSurface();


          so the surface will be redrawn and then saving the image.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 9 at 8:14

























          answered Nov 9 at 8:02









          Markus Michel

          1,402214




          1,402214












          • Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
            – Nihal Sekhar
            Nov 12 at 4:59










          • I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
            – Nihal Sekhar
            Nov 12 at 7:33












          • After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
            – Markus Michel
            Nov 12 at 7:48






          • 1




            I really do not know how to thank you enough.May god bless you. It works like a beaut.
            – Nihal Sekhar
            Nov 12 at 8:43




















          • Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
            – Nihal Sekhar
            Nov 12 at 4:59










          • I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
            – Nihal Sekhar
            Nov 12 at 7:33












          • After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
            – Markus Michel
            Nov 12 at 7:48






          • 1




            I really do not know how to thank you enough.May god bless you. It works like a beaut.
            – Nihal Sekhar
            Nov 12 at 8:43


















          Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
          – Nihal Sekhar
          Nov 12 at 4:59




          Woah man WHY DIDNT I THINK OF THIS. Thanks a ton @markus I shall implement this right away.
          – Nihal Sekhar
          Nov 12 at 4:59












          I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
          – Nihal Sekhar
          Nov 12 at 7:33






          I tried implementing but the canvasView doesnt change according to the modes. I think the problem is in canvasView.InvalidateSurface(); I tried using this everywhere inside the onclick method. But it doesn't seem to redraw a new surface. It takes the old one. Like if i click speia first, it changes to sepia but after that if i click grayscale it still takes sepia. I put console on the onpaintsurface method and it doesn't hit after clicking anything after the first mode.... I hope you understood.
          – Nihal Sekhar
          Nov 12 at 7:33














          After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
          – Markus Michel
          Nov 12 at 7:48




          After looking at your functions again, I noticed that canvasView is being created in your tapped methods without being added anywhere on the screen. So basically your canvas view exists somewhere in memory but never on the screen and therefore will never draw anything. However this should be an easy fix. In your xaml, give the (hopefully only) SKCanvasView the property "x:Name="CanvasView". Now you can call CanvasView.InvalidateSurface() in your button tapped methods.
          – Markus Michel
          Nov 12 at 7:48




          1




          1




          I really do not know how to thank you enough.May god bless you. It works like a beaut.
          – Nihal Sekhar
          Nov 12 at 8:43






          I really do not know how to thank you enough.May god bless you. It works like a beaut.
          – Nihal Sekhar
          Nov 12 at 8:43




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53220214%2fhow-to-call-paintsurface-twice-in-skiasharp-xamarin-forms%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()