在 MPAndroidChart 中将图表保存为图像
Saving a chart as an image in MPAndroidChart
我正在使用 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);
}
}
来自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(启用布尔值)
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.
因此,根据建议,使用 PixelCopy 来获取 UI.It 的 API 24 级及以上可用的屏幕截图/快照
PixelCopy.request(surfaceViewObject,BitmapDest,listener,new Handler());
其中,
surfaceViewObject是surface view的对象
BitmapDest 是保存图像的位图对象,不能为空
侦听器是 OnPixelCopyFinishedListener
有关更多信息,请参阅 Pixel Copy Android Documentation
使用 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
和高度的原因是,当您有一个可滚动视图或 ViewGroup
时,屏幕截图会被剪裁。
我正在使用 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);
}
}
来自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(启用布尔值)
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.
因此,根据建议,使用 PixelCopy 来获取 UI.It 的 API 24 级及以上可用的屏幕截图/快照
PixelCopy.request(surfaceViewObject,BitmapDest,listener,new Handler());
其中,
surfaceViewObject是surface view的对象
BitmapDest 是保存图像的位图对象,不能为空
侦听器是 OnPixelCopyFinishedListener
有关更多信息,请参阅 Pixel Copy Android Documentation
使用 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
和高度的原因是,当您有一个可滚动视图或 ViewGroup
时,屏幕截图会被剪裁。