Save bitmap to file function

116,159

Solution 1

  1. You need an appropriate permission in manifest.xml:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
  2. out.flush() check the out is not null..

  3. String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + 
                                "/PhysicsSketchpad";
    File dir = new File(file_path);
    if(!dir.exists())
        dir.mkdirs();
    File file = new File(dir, "sketchpad" + pad.t_id + ".png");
    FileOutputStream fOut = new FileOutputStream(file);
    
    bmp.compress(Bitmap.CompressFormat.PNG, 85, fOut);
    fOut.flush();
    fOut.close();
    

Solution 2

In kotlin :

private fun File.writeBitmap(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int) {
    outputStream().use { out ->
        bitmap.compress(format, quality, out)
        out.flush()
    }
}

usage example:

File(exportDir, "map.png").writeBitmap(bitmap, Bitmap.CompressFormat.PNG, 85)

Edit: This was my original answer and its nice, but lately I use this:

fun File.createFileAndDirs() = apply {
    parentFile?.mkdirs()
    createNewFile()
}

fun File.write(
    bitmap: Bitmap, format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG, quality: Int = 80
) = apply {
    createFileAndDirs()
    outputStream().use {
        bitmap.compress(format, quality, it)
        it.flush()
    }
}

It's better because there are some useful defaults in-place and also it creates file if it doesn't exist.

Solution 3

Two example works for me, for your reference.

Bitmap bitmap = Utils.decodeBase64(base64);
try {
    File file = new File(filePath);
    FileOutputStream fOut = new FileOutputStream(file);
    bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
    fOut.flush();
    fOut.close();
}
catch (Exception e) {
    e.printStackTrace();
    LOG.i(null, "Save file error!");
    return false;
}

and this one

Bitmap savePic = Utils.decodeBase64(base64);
File file = new File(filePath);
File path = new File(file.getParent());

if (savePic != null) {
    try {
        // build directory
        if (file.getParent() != null && !path.isDirectory()) {
            path.mkdirs();
        }
        // output image to file
        FileOutputStream fos = new FileOutputStream(filePath);
        savePic.compress(Bitmap.CompressFormat.PNG, 90, fos);
        fos.close();
        ret = true;
    } catch (Exception e) {
        e.printStackTrace();
    }
} else {
    LOG.i(TAG, "savePicture image parsing error");
}

Solution 4

Here is the function which help you

private void saveBitmap(Bitmap bitmap,String path){
        if(bitmap!=null){
            try {
                FileOutputStream outputStream = null;
                try {
                    outputStream = new FileOutputStream(path); //here is set your file path where you want to save or also here you can set file object directly

                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); // bitmap is your Bitmap instance, if you want to compress it you can compress reduce percentage
                    // PNG is a lossless format, the compression factor (100) is ignored
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (outputStream != null) {
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }    
        }
    }
Share:
116,159

Related videos on Youtube

Oliver Dixon
Author by

Oliver Dixon

Updated on July 09, 2022

Comments

  • Oliver Dixon
    Oliver Dixon almost 2 years

    I'm trying to save a bitmap to file and a specific directly using a function I've created. It's not working. It crashes after bitmap.compress part (before here3).

        File dir = new File(filepath);
    
        if(!dir.exists())dir.mkdirs();
    
        File file = new File(Environment.getExternalStorageDirectory() + filepath, side + ".png");
        FileOutputStream fOut = new FileOutputStream(file);
    
        bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
        fOut.flush();
        fOut.close();
    
        System.out.println(filepath);
    
        bitmap.recycle();
        System.gc();
    

    Error log:

    06-29 00:16:38.089: D/AndroidRuntime(3260): Shutting down VM
    06-29 00:16:38.089: W/dalvikvm(3260): threadid=1: thread exiting with uncaught exception (group=0xb587f4f0)
    06-29 00:16:38.089: E/AndroidRuntime(3260): FATAL EXCEPTION: main
    06-29 00:16:38.089: E/AndroidRuntime(3260): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=android.intent.action.VIEW dat=content://org.openintents.filemanager/mimetype//mnt/sdcard/download/02977_awreckedboatintheocean_1280x1024.jpg }} to activity {com.polygonattraction.testbirds/com.polygonattraction.testbirds.functions.SelectImageSource}: java.lang.IllegalStateException: Can't compress a recycled bitmap
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread.access$2000(ActivityThread.java:117)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.os.Handler.dispatchMessage(Handler.java:99)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.os.Looper.loop(Looper.java:130)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread.main(ActivityThread.java:3683)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at java.lang.reflect.Method.invokeNative(Native Method)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at java.lang.reflect.Method.invoke(Method.java:507)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at dalvik.system.NativeStart.main(Native Method)
    06-29 00:16:38.089: E/AndroidRuntime(3260): Caused by: java.lang.IllegalStateException: Can't compress a recycled bitmap
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.graphics.Bitmap.checkRecycled(Bitmap.java:180)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.graphics.Bitmap.compress(Bitmap.java:581)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at com.polygonattraction.testbirds.functions.Functions.SaveToFile(Functions.java:144)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at com.polygonattraction.testbirds.functions.SelectImageSource.onActivityResult(SelectImageSource.java:113)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.Activity.dispatchActivityResult(Activity.java:3908)
    06-29 00:16:38.089: E/AndroidRuntime(3260):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
    
    • Dheeresh Singh
      Dheeresh Singh almost 12 years
      "Can't compress a recycled bitmap.".have you called bitmap.recycle(); any where before this ?
    • Trevor Hart
      Trevor Hart over 6 years
      Side note, if you don't need to collect that bitmap right then and there, you should delay a major collection as long as possible for your apps performance sake, I'd mark everything you need to collect, and then after you've marked everything call for a collection.
  • Dheeresh Singh
    Dheeresh Singh almost 12 years
    sorry not get , are you want to write file if it not exists only ?
  • laalto
    laalto almost 6 years
    Please note the android tag in the question
  • Kirill Karmazin
    Kirill Karmazin over 5 years
    compress rate 85 will be skipped for PNG, as for the JPEG - 90 is optimal.