[android] Save bitmap to file function

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)

This question is related to android file-io android-intent bitmap android-file

The answer is


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)

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

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

implementation save bitmap and load bitmap directly. fast and ease on mfc class

void CMRSMATH1Dlg::Loadit(TCHAR *destination, CDC &memdc)
{
CImage img;
PBITMAPINFO bmi;
BITMAPINFOHEADER Info;
BITMAPFILEHEADER bFileHeader;
CBitmap bm;     
CFile file2;
file2.Open(destination, CFile::modeRead | CFile::typeBinary);
file2.Read(&bFileHeader, sizeof(BITMAPFILEHEADER));
file2.Read(&Info, sizeof(BITMAPINFOHEADER));    
BYTE ch;
int width = Info.biWidth;
int height = Info.biHeight;
if (height < 0)height = -height;
int size1 = width*height * 3;
int size2 = ((width * 24 + 31) / 32) * 4 * height;
int widthnew = (size2 - size1) / height;
BYTE * buffer = (BYTE *)GlobalAlloc(GPTR, size2);
//////////////////////////
HGDIOBJ old;
unsigned char alpha = 0;    
int z = 0;  
z = 0;
int gap = (size2 - size1) / height;
for (int y = 0;y < height;y++)
{
    for (int x = 0;x < width*3;x++)
    {
        file2.Read(&ch, 1);
        buffer[z] = ch;
        z++;
    }
    for (int z1 = 0;z1 <gap;z1++)
    {
        file2.Read(&ch,1);
    }
}
bm.CreateCompatibleBitmap(&memdc, width, height);
bm.SetBitmapBits(size1,buffer);
old = memdc.SelectObject(&bm);   
///////////////////////////  
 //bm.SetBitmapBits(size1, buffer);     
 GetDC()->BitBlt(1, 95, width, height, &memdc, 0, 0, SRCCOPY);
 memdc.SelectObject(&old);
 bm.DeleteObject();
 GlobalFree(buffer);     
 file2.Close();
 }
 void CMRSMATH1Dlg::saveit(CBitmap &bit1, CDC &memdc, TCHAR *destination)
  {     
BITMAP bm;
PBITMAPINFO bmi;
BITMAPINFOHEADER Info;
BITMAPFILEHEADER bFileHeader;
CFile file1;
            CSize size = bit1.GetBitmap(&bm);
 int z = 0;  
 BYTE ch = 0;
 size.cx = bm.bmWidth;
 size.cy = bm.bmHeight;
 int width = size.cx;    
 int size1 = (size.cx)*(size.cy);
 int size2 = size1 * 3;  
 size1 = ((size.cx * 24 + 31) / 32) *4* size.cy;     
 BYTE * buffer = (BYTE *)GlobalAlloc(GPTR, size2);               
 bFileHeader.bfType = 'B' + ('M' << 8); 
 bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 bFileHeader.bfSize = bFileHeader.bfOffBits + size1;
 bFileHeader.bfReserved1 = 0;
 bFileHeader.bfReserved2 = 0;   
 Info.biSize = sizeof(BITMAPINFOHEADER);
 Info.biPlanes = 1;
 Info.biBitCount = 24;//bm.bmBitsPixel;//bitsperpixel///////////////////32
 Info.biCompression = BI_RGB;
 Info.biWidth =bm.bmWidth;
 Info.biHeight =-bm.bmHeight;///reverse pic if negative height
 Info.biSizeImage =size1;
 Info.biClrImportant = 0;
 if (bm.bmBitsPixel <= 8)
 {
     Info.biClrUsed = 1 << bm.bmBitsPixel;
 }else
 Info.biClrUsed = 0;
 Info.biXPelsPerMeter = 0;
 Info.biYPelsPerMeter = 0;
 bit1.GetBitmapBits(size2, buffer);      
 file1.Open(destination, CFile::modeCreate | CFile::modeWrite |CFile::typeBinary,0);
 file1.Write(&bFileHeader, sizeof(BITMAPFILEHEADER));
 file1.Write(&Info, sizeof(BITMAPINFOHEADER));
 unsigned char alpha = 0;    
 for (int y = 0;y<size.cy;y++)
 {
     for (int x = 0;x<size.cx;x++)
     {
         //for reverse picture below
         //z = (((size.cy - 1 - y)*size.cx) + (x)) * 3;          
     z = (((y)*size.cx) + (x)) * 3;
     file1.Write(&buffer[z], 1);
     file1.Write(&buffer[z + 1], 1);
     file1.Write(&buffer[z + 2], 1);
     }               
     for (int z = 0;z < (size1 - size2) / size.cy;z++)
     {
         file1.Write(&alpha, 1);
     }
 }   
 GlobalFree(buffer);     
 file1.Close();  
 file1.m_hFile = NULL;
        }

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to file-io

Python, Pandas : write content of DataFrame into text File Saving response from Requests to file How to while loop until the end of a file in Python without checking for empty line? Getting "java.nio.file.AccessDeniedException" when trying to write to a folder How do I add a resources folder to my Java project in Eclipse Read and write a String from text file Python Pandas: How to read only first n rows of CSV files in? Open files in 'rt' and 'wt' modes How to write to a file without overwriting current contents? Write objects into file with Node.js

Examples related to android-intent

Kotlin Android start new Activity Open Facebook Page in Facebook App (if installed) on Android Android - Adding at least one Activity with an ACTION-VIEW intent-filter after Updating SDK version 23 Not an enclosing class error Android Studio Parcelable encountered IOException writing serializable object getactivity() Sending intent to BroadcastReceiver from adb How to pass ArrayList<CustomeObject> from one activity to another? Android Intent Cannot resolve constructor Android Gallery on Android 4.4 (KitKat) returns different URI for Intent.ACTION_GET_CONTENT Android - java.lang.SecurityException: Permission Denial: starting Intent

Examples related to bitmap

How to solve java.lang.OutOfMemoryError trouble in Android Save and retrieve image (binary) from SQL Server using Entity Framework 6 How to create bitmap from byte array? Fastest way to convert Image to Byte array How to save a bitmap on internal storage Android set bitmap to Imageview Save bitmap to file function How to resize Image in Android? Android Bitmap to Base64 String Android load from URL to Bitmap

Examples related to android-file

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData() How to access /storage/emulated/0/ Simple mediaplayer play mp3 from file path? Trying to create a file in Android: open failed: EROFS (Read-only file system) Save bitmap to file function Difference between mkdir() and mkdirs() in java for java.io.File Show Image View from file path? How to create directory automatically on SD card