在 MPAndroidChart 中将图表保存为图像

Posted

技术标签:

【中文标题】在 MPAndroidChart 中将图表保存为图像【英文标题】:Saving a chart as an image in MPAndroidChart 【发布时间】:2015-07-02 23:29:12 【问题描述】:

我正在使用 MPandroidChart 来呈现各种图表。我想添加将图表保存为图库的功能。我在操作栏中添加了一个图标以使用此功能,但图像未保存到图库中。

代码如下:

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

【问题讨论】:

你有没有在你的清单中写入外部存储权限 添加权限就可以了。 :D 【参考方案1】:

来自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();

更新

感谢 tamim 指出此弃用。这是更新的解决方案

public void setDrawingCacheEnabled(启用布尔值)

此方法在 API 级别 28 中已弃用。视图绘图缓存为 随着硬件加速的引入,在很大程度上已经过时 在 API 11 中渲染。使用硬件加速,中间缓存 层在很大程度上是不必要的,并且很容易导致净损失 由于创建和更新层的成本而导致的性能。在里面 缓存层有用的极少数情况,例如用于 alpha 动画, setLayerType(int, android.graphics.Paint) 处理这个 与硬件渲染。对于软件渲染的小型快照 视图层次结构或单个视图的一部分,建议 从位图或图片创建画布并调用 在视图上绘制(android.graphics.Canvas)。然而这些 不鼓励使用软件渲染的用法,并且存在兼容性问题 具有纯硬件渲染功能,例如 Config.HARDWARE 位图, 实时阴影和轮廓剪裁。对于 UI 的屏幕截图 建议使用反馈报告或对 PixelCopy API 进行单元测试。

因此,根据建议,使用 PixelCopy 获取 UI 的屏幕截图/快照。它适用于 API 级别 24 及更高级别

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

在哪里,

surfaceViewObject 是表面视图的对象

BitmapDest 是要保存图片的位图对象,不能为空

监听器是 OnPixelCopyFinishedListener

更多信息请参考Pixel Copy Android Documentation

【讨论】:

setdrawingcacheenabled 现在在 api 28 上已弃用,还有其他我们可以安全使用的方法吗? 感谢您的解决方案。如果您想在不使用 PixelCopy 的情况下实现此目的,请查看我的答案,因为在某些情况下您需要直接使用位图而不是通过回调。【参考方案2】:

使用 Kotlin 扩展,我能够以这种方式实现它:

//create a bitmap using view height and width to draw to it
fun View.getBitmap(): Bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888).also 
    //create a canvas for this bitmap (it)
    Canvas(it).apply 
        //if the view has a background, draw it to the canvas, else draw a white screen 
        //because canvas default background is black
        background?.draw(this) ?: drawColor(Color.WHITE)
        //draw the view to the canvas
        draw(this)
    

我使用 measuredWidth 和 Height 的原因是因为当您有可滚动视图或 ViewGroup 时,屏幕截图会被剪裁。

【讨论】:

以上是关于在 MPAndroidChart 中将图表保存为图像的主要内容,如果未能解决你的问题,请参考以下文章

MPAndroidChart开源图表库之饼状图

Android图表库MPAndroidChart(十四)——在ListView种使用相同的图表

MPAndroidChart - 更改消息“没有可用的图表数据”

我可以在 Flutter 中使用类似 MPAndroidChart 的图表吗? [关闭]

Android图表库MPAndroidChart——条形图的绘制过程过程,隐隐约约我看到了套路

Android图表 MPAndroidChart折线图