androidmpandroidchartsave-image

Saving a chart as an image in MPAndroidChart


I am using the MPAndroidChart to render various charts. I wanted to add the functionality of saving the charts as images to the gallery. I added an icon to the action bar to use this functionality, but the image does not save to the gallery.

The code is given below :

<item android:id="@+id/save"
    android:icon="@drawable/ic_action_accept"
    android:title="@string/save"
    app:showAsAction="always"/>

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    switch (item.getItemId()) {
        case R.id.save :
            mlineChart.saveToGallery("Chart",50);
            return true;
        case R.id.action_settings :
            return true;
        default: return super.onOptionsItemSelected(item);
    }
}

Solution

  • From How to programatically take a screenshot on Android?

    // image naming and path  to include sd card  appending name you choose for file
    String mPath = Environment.getExternalStorageDirectory().toString() + "/" + ACCUWX.IMAGE_APPEND;   
    // create bitmap screen capture
    Bitmap bitmap;
    View v1 = mWebview.getRootView(); // take the view from your webview
    v1.setDrawingCacheEnabled(true);
    bitmap = Bitmap.createBitmap(v1.getDrawingCache());
    v1.setDrawingCacheEnabled(false);
    
    OutputStream fout = null;
    imageFile = new File(mPath);
    
    try {
      fout = new FileOutputStream(imageFile);
      bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
      fout.flush();
      fout.close();
    
    } catch (FileNotFoundException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    

    Update

    Thanks tamim for pointing this deprecation out. Here is the updated solution

    public void setDrawingCacheEnabled (boolean enabled)

    This method was deprecated in API level 28. The view drawing cache was largely made obsolete with the introduction of hardware-accelerated rendering in API 11. With hardware-acceleration, intermediate cache layers are largely unnecessary and can easily result in a net loss in performance due to the cost of creating and updating the layer. In the rare cases where caching layers are useful, such as for alpha animations, setLayerType(int, android.graphics.Paint) handles this with hardware rendering. For software-rendered snapshots of a small part of the View hierarchy or individual Views it is recommended to create a Canvas from either a Bitmap or Picture and call draw(android.graphics.Canvas) on the View. However these software-rendered usages are discouraged and have compatibility issues with hardware-only rendering features such as Config.HARDWARE bitmaps, real-time shadows, and outline clipping. For screenshots of the UI for feedback reports or unit testing the PixelCopy API is recommended.

    So as per the recommendations use PixelCopy for fetching screenshots / snapshot of the UI.It's available in API level 24 and above

    PixelCopy.request(surfaceViewObject,BitmapDest,listener,new Handler());
    

    where,

    surfaceViewObject is the object of surface view

    BitmapDest is the bitmap object where the image will be saved and it cant be null

    listener is OnPixelCopyFinishedListener

    for more info refer Pixel Copy Android Documentation