Using SkiaSharp, how to save a SKBitmap ?

MabroukMabrouk USMember ✭✭✭

After editing a SKBitmap in Xamarin.Forms i wanna save it in local storage.

Any idea?

Best Answer

Answers

  • mattleibowmattleibow ZAXamarin Team Xamurai

    @Mabrouk You can save an SKImage. The SKBitmap type is designed for representing the actual bytes in memory, so you need to first convert it into an image and then save that. To do this you:

    // create an image and then get the PNG (or any other) encoded data
    using (var image = SKImage.FromBitmap(bitmap))
    using (var data = image.Encode(SKImageEncodeFormat.Png, 80)) {
        // save the data to a stream
        using (var stream = File.OpenWrite("path/to/image.png")) {
            data.SaveTo(stream);
        }
    }
    

    That should work, and you can then load the image using whatever tool you want. Also note, You can save a SKSurface using the Snapshot method which returns an SKImage also.

  • MabroukMabrouk USMember ✭✭✭

    @mattleibow Thanks for that, but in PCL project File class do not exists, if i use Java.IO.File then OpenWrite do not exists ... how to fix that? :smile:

  • mattleibowmattleibow ZAXamarin Team Xamurai

    @Mabrouk Well, there are a few ways, but I would recommend this doc:
    https://developer.xamarin.com/guides/xamarin-forms/working-with/files/

    Also note at the bottom "PCL Storage", which is a PCL filesystem plugin:
    https://www.nuget.org/packages/PCLStorage/

  • MabroukMabrouk USMember ✭✭✭

    @mattleibow Thanks :)

  • JoseMirallesJoseMiralles USMember ✭✭
    edited February 2017

    (I just realized that I am in the wrong thread, I meant to post this in the SkiaSharp.Views forum post.)

    Is there anyway of displaying an already created SKBitmap or SKCanvas in a view?
    I just installed "SkiaSharp.Views" but I can't find a way of doing so.

  • mattleibowmattleibow ZAXamarin Team Xamurai

    @JoseMiralles Right now there is no way to just set view.Bitmap = myBitmap. You will have to implement the paint event and draw the image yourself.

    I was thinking about this just a few hours ago, and I am looking at adding something like this in the coming release. I created an issue to track this: https://github.com/mono/SkiaSharp/issues/255

    Please feel free to leave comments or any suggestions that will help with meeting your needs.

  • EddieMEddieM USMember ✭✭

    Versions

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="PCLStorage" version="1.0.2" targetFramework="portable45-net45+win8+wp8+wpa81" />
      <package id="SkiaSharp" version="1.59.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
      <package id="SkiaSharp.Views.Forms" version="1.59.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
      <package id="Xamarin.Forms" version="2.3.3.193" targetFramework="portable45-net45+win8+wp8+wpa81" />
    </packages>
    
  • EddieMEddieM USMember ✭✭

    Solved my own issue. It was actually clipping it by 50%. Changing the following line fixed the issue. I am new to all of this. So, I will have to look into why Android is fine with what is stored in _canvasView.Height and _canvasView.Width while iOS requires them to be doubled.

    SKBitmap bitmap = new SKBitmap((int) _canvasView.Width, (int) _canvasView.Height);

    to

    SKBitmap bitmap = new SKBitmap((int) _canvasView.Width * 2, (int) _canvasView.Height * 2);

  • EddieMEddieM USMember ✭✭

    Sorry for all the posts. Just figuring it out as I go. Actually If I use _canvasView.CanvasSize I will get the correct height and width in both environments. Only in iOS will the height and width from _canvasView be half of what comes from _canvasView.CanvasSize.....BTW _canvasView is SKCanvasView. Visually there does not appear to be an issue with using _canvasView.CanvasSize when creating my SKBitmap. Does anyone know if this is an issue to do this? Came across this post.

    https://forums.xamarin.com/discussion/88963/skcanvasview-size-property-contradiction

  • mattleibowmattleibow ZAXamarin Team Xamurai

    @EddieM That is the correct way to get the canvas size.

    canvasView.Width will return the width of the view in device independent pixels. canvasView.CanvasSize.Width will return the actual pixels.

  • EddieMEddieM USMember ✭✭

    @mattleibow Cool, thanks!

  • EddieMEddieM USMember ✭✭
    edited September 2017

    @mattleibow
    Hey, everything is working correctly. Only difference now is that I stored the png file to the external directory. The image can be encoded and decoded with SkiaSharp and shows correctly on a canvas but when viewing from the file system the images are always just completely black. Any idea why? I have done some searching but none of the options I found work.

    Additional Info
    Seems to be an Android issue. If I go look at the file from my PC (Computer -> Drive Letter of device) or even move the file over to my PC. I see the image just fine.

  • ajbeemajbeem Member ✭✭

    Hi , I trying to get the canvas but SkiaSharp Cropping 2/3 parts of image, why its happend?

Sign In or Register to comment.