我有一个应用程序,它在TableLayout中生成一个具有可变数量的TableRows的报表。
我使用以下代码将表捕获到位图中:
TableLayout tl = (TableLayout)findViewById(R.id.CSRTableLayout);
Bitmap csr = Bitmap.createBitmap(tl.getWidth(), tl.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(csr);
tl.draw(canvas);
将屏幕捕获为位图后,我将其附加到电子邮件中:
//folder already exists
File file = new File(folder.getAbsolutePath()+"/CSR"+csrnum+".jpg");
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
fos=new FileOutputStream(file);
bos=new BufferedOutputStream(fos);
if(bos!=null) {
try {
csr.compress(Bitmap.CompressFormat.JPEG, 60, bos);
} catch (OutOfMemoryError e) {
Toast.makeText(CustomerReportActivity.this, "Out of Memory!", Toast.LENGTH_SHORT).show();
} finally {
fos.flush();
fos.close();
bos.flush();
bos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
if(file.exists()) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setType("message/rfc822");
String emailTo[] = {"***@****.***"};
i.putExtra(Intent.EXTRA_EMAIL,emailTo);
i.putExtra(Intent.EXTRA_SUBJECT,"...");
i.putExtra(Intent.EXTRA_TEXT, "...");
i.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://"+file.getAbsolutePath()));
startActivity(i);
} else {
Toast.makeText(CustomerReportActivity.this, "Error attaching report to email!", Toast.LENGTH_SHORT).show();
}
问题是有时桌子会变得很大,例如1600x2400dp。我在“Bitmap.createBitmap(...)”行上得到一个OutOfMemoryError是否有另一种方法来捕获屏幕而不会溢出VM堆?如果我理解正确的话,调用Bitmap.createBitmap(...)就是创建一个完整大小的位图,它只是纯白色。是否可以使用无像素数据创建它,并且只在我调用csr.compress(...)时填充它以便它保持小?任何想法/建议都非常感谢!提前谢谢!
答案 0 :(得分:0)
有几天我有同样的任务要做。 如果您想要捕获屏幕并且该图像应该通过电子邮件发布,那么请研究我曾经用过的以下代码:
saveImageInLandscapFunction(); // function to save the Image
Intent picMessageIntent = new Intent(android.content.Intent.ACTION_SEND);
picMessageIntent.setType("image/jpeg");
File f = new File(APP_FILE_PATH + "/"+filename+".jpg");
picMessageIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
startActivity(picMessageIntent);
使用screenShot并保存到SD卡的功能
protected void saveImageInLandscapFunction() {
View root = findViewById(android.R.id.content);
root.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(root.getDrawingCache());
//Bitmap bm = Bitmap.createBitmap(root.getDrawingCache(), 0, 0, display.getWidth(), display.getHeight());
root.setDrawingCacheEnabled(false);
// Bitmap overlayBitmap = overlay(photoBitmap, mBitmap); // overlay the Bitmap
new ExportBitmapToFile(DrawMainActivity.this, bm).execute();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
处理主保存图像处理并显示进度条直到图像保存的类:
// for to saw progressBar
public static class ExportBitmapToFile extends AsyncTask<Intent,Void,Boolean> {
private Context mContext;
private Handler mHandler;
private Bitmap nBitmap;
private ProgressDialog m_progressDialog = null;
@Override
protected void onPreExecute(){
m_progressDialog = new ProgressDialog(mContext);
m_progressDialog.setTitle("Draw");
m_progressDialog.setMessage("Please wait...");
m_progressDialog.setCancelable(false);
m_progressDialog.show();
}
public ExportBitmapToFile(Context context,Bitmap bitmap) {
mContext = context;
nBitmap = bitmap;
}
@Override
protected Boolean doInBackground(Intent... arg0) {
try {
if (!APP_FILE_PATH.exists()) {
APP_FILE_PATH.mkdirs();
}
final FileOutputStream out = new FileOutputStream(new File(APP_FILE_PATH + "/"+filename+".jpg"));
nBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
return true;
}catch (Exception e) {
e.printStackTrace();
}
//mHandler.post(completeRunnable);
return false;
}
@Override
protected void onPostExecute(Boolean bool) {
super.onPostExecute(bool);
if ( bool ){
//mHandler.sendEmptyMessage(1);
}
if (m_progressDialog.isShowing()) {
m_progressDialog.dismiss();
}
}
}
希望这对你很有帮助。
如果您需要其他帮助,请告诉我。
享受。 :)
答案 1 :(得分:0)
为什么不将图像分成多个较小的区域并发送....然后你可以将它们缝合回来......或者如果你有耐心和技巧......你可以通过阅读保存在磁盘上的较小图像文件并发送拼接图像...您可以在发送到draw()方法之前使用翻译和剪辑画布来获取所需的区域
答案 2 :(得分:0)
在创建位图时,为什么不用硬度来表示宽度和高度。
Bitmap result = Bitmap.createScaledBitmap(bitmapPicture,
640, 480, false);
试试这个,请告诉我这是否有任何帮助。
答案 3 :(得分:0)
尝试将您的解决方案和iDroid Explorer的解决方案结合起来。检查是否可以直接从绘图缓存写入文件。你的代码看起来会这样:
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
if(bos!=null) {
try {
TableLayout tl = (TableLayout)findViewById(R.id.CSRTableLayout);
tl.setDrawingCacheEnabled(true);
Bitmap csr = tl.getDrawingCache();
csr.compress(Bitmap.CompressFormat.JPEG, 60, bos);
tl.setDrawingCacheEnabled(false);
} catch (OutOfMemoryError e) {
Toast.makeText(CustomerReportActivity.this, "Out of Memory!", Toast.LENGTH_SHORT).show();
} finally {
bos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
也许,您需要在关闭绘图缓存后回收csr
。
答案 4 :(得分:0)
不幸的是,没有办法避免我的问题。我只需要使用较低质量的设置,并希望尺寸不会变得太大。尝试缩放位图无法正常工作,最终导致图像失真。