8

I am trying to save a bitmap image to a directory (gallery) inside my phone. The app is being developed in Xamarin so the code is C#.

I cant seem to figure out how to make a directory, and save a Bitmap. Any suggestions?

public void createBitmap(View view){ 
    view.DrawingCacheEnabled = true; 
    view.BuildDrawingCache (true); 
    Bitmap m_Bitmap = view.GetDrawingCache(true);

    String storagePath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
    Java.IO.File storageDirectory = new Java.IO.File(storagePath);
    //storageDirectory.mkdirs ();


    //save the bitmap
    //MemoryStream stream = new MemoryStream ();
    //m_Bitmap.Compress (Bitmap.CompressFormat.Png, 100, stream);
    //stream.Close();


    try{

        String filePath = storageDirectory.ToString() + "APPNAME.png";
        FileOutputStream fos = new FileOutputStream (filePath);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        m_Bitmap.Compress (Bitmap.CompressFormat.Png, 100, bos);
        bos.Flush();
        bos.Close();
    } catch (Java.IO.FileNotFoundException e) {
        System.Console.WriteLine ("FILENOTFOUND");
    } catch (Java.IO.IOException e) {
        System.Console.WriteLine ("IOEXCEPTION");
    }
Fnr
  • 2,096
  • 7
  • 41
  • 76
Coova
  • 1,818
  • 5
  • 36
  • 63

2 Answers2

24

This here is a slim way to export a Bitmap as PNG-file to the sd-card using only C# stuff:

void ExportBitmapAsPNG(Bitmap bitmap)
{
    var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
    var filePath = System.IO.Path.Combine(sdCardPath, "test.png");
    var stream = new FileStream(filePath, FileMode.Create);
    bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
    stream.Close();
}
kaolick
  • 4,817
  • 5
  • 42
  • 53
  • 1
    how do you write out the raw bmp data without compressing? – gonzobrains Jun 29 '16 at 18:03
  • @gonzobrains I don't know if or how that's possible. Sorry. – kaolick Jun 30 '16 at 07:18
  • 3
    You should release steam and bitmap from memory by using ".Dispose()" or it may be better to use "using(){}". – Wessam El Mahdy Oct 07 '17 at 21:57
  • when I compress it I'm losing the quality of the image. is there a way to save it without passing to this compress function? Also, the post @testing showed only shows to convert to byte array by passing it to the compress function. – Fnr Nov 28 '17 at 11:39
  • 1
    @Fabiotk: Have you tried [`CopyPixelsToBuffer()`](https://developer.xamarin.com/api/member/Android.Graphics.Bitmap.CopyPixelsToBuffer/p/Java.Nio.Buffer/)? [Here](https://forums.xamarin.com/discussion/5950/how-to-convert-from-bitmap-to-byte-without-bitmap-compress) is a post about this. – testing Nov 28 '17 at 13:52
  • @Fabiotk another option you might try is GetByteArrayFromImage(). – xanderh Aug 05 '19 at 12:39
3

Change:

String filePath = storageDirectory.ToString() + "APPNAME.png";

To:

String filePath = Path.Combine(storageDirectory.ToString(), "APPNAME.png");

Your original code appends the file name to the last folder in the path name without adding a path separator. For example, path of \data\data\sdcard01 would create a file path of \data\data\sdcard01APPNAME.png. Using Path.Combine() ensures that a path separator is used when appending directories.

matthewrdev
  • 11,930
  • 5
  • 52
  • 64