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
xamarin xamarin.forms xamarin.ios xamarin.android skiasharp
add a comment |
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
xamarin xamarin.forms xamarin.ios xamarin.android skiasharp
add a comment |
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
xamarin xamarin.forms xamarin.ios xamarin.android skiasharp
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
xamarin xamarin.forms xamarin.ios xamarin.android skiasharp
asked Nov 9 at 5:13
Nihal Sekhar
62
62
add a comment |
add a comment |
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.
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 incanvasView.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
add a comment |
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.
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 incanvasView.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
add a comment |
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.
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 incanvasView.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
add a comment |
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.
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.
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 incanvasView.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
add a comment |
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 incanvasView.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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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