Android растровые изображения и захват экрана - PullRequest
2 голосов
/ 17 января 2012

У меня есть приложение, которое генерирует отчет в 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.Я получил OutOfMemoryError в строке «Bitmap.createBitmap (...)» Есть ли альтернативный метод для захвата экрана без переполнения кучи виртуальной машины?Если я правильно понимаю, вызов Bitmap.createBitmap (...) создает растровое изображение полного размера, которое просто белое.Можно ли создать его без данных о пикселях и заполнить его только один раз, когда я позвонил csr.compress (...), чтобы он оставался маленьким?Любые идеи / предложения с благодарностью!Заранее спасибо!

Ответы [ 5 ]

0 голосов
/ 19 июля 2012

К сожалению, не было никакого способа избежать моей проблемы. Мне просто пришлось использовать более низкую настройку качества и надеяться, что размер не станет слишком большим. Попытка масштабирования растрового изображения не сработала должным образом, и в результате получилось искаженное изображение.

0 голосов
/ 29 января 2012

Попробуйте объединить ваше решение с 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 после отключения кэша чертежа.

0 голосов
/ 27 января 2012

Почему бы вам не разбить изображения на несколько небольших областей и отправить ... затем вы можете сшить их обратно ... или, если у вас есть терпение и умение ... вы можете сшить изображения, прочитав меньшие файлы изображений сохраняются на диске и отправляют сшитое изображение ... Вы можете использовать перевод и обрезать холст перед отправкой в ​​метод draw (), чтобы получить нужные регионы

0 голосов
/ 27 января 2012

При создании растрового изображения, почему вы не жестко хардкор ширины и высоты.

Bitmap result = Bitmap.createScaledBitmap(bitmapPicture,
                        640, 480, false);

Попробуйте, дайте мне знать, если это поможет или нет.

0 голосов
/ 24 января 2012

За несколько дней до того, как я выполнил ту же задачу.Если вы хотите сделать снимок экрана, и это изображение должно быть отправлено по электронной почте, пожалуйста, изучите приведенный ниже код, который я использовал для этого:

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

Функция, которая принимает снимок экрана и сохраняет его на 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();          
        }  
    }
}

Надеюсь, это вам поможет.

Дайте мне знать, еслиВам нужна другая помощь.

Наслаждайтесь.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...