检测大尺寸图像中的面部时应用程序崩溃

时间:2016-04-14 06:34:28

标签: android android-studio out-of-memory

我从手机的图库中提取图像并将其设置在图像视图中并使用谷歌的移动视觉库试图检测该图像中的脸部。我也缩小了图像大小,所以现在第一个大尺寸图像将正确加载到图像视图中,但如果您尝试加载另一个大尺寸图像,应用程序将崩溃。此外,在检测大尺寸图像的面部时,应用程序正在崩溃,这些应用程序正在崩溃。

Logcat:logcat

MainActivity.java

package com.imagegallery.app.imagegallery;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.face.Face;
import com.google.android.gms.vision.face.FaceDetector;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

public class MainActivity extends AppCompatActivity  implements View.OnClickListener {

private int PICK_IMAGE_REQUEST=1;
Button btnLoad, btnDetFace;
int count=0;
Context cntx;
String open_time,close_time;
DatabaseHandler db = new DatabaseHandler(this);
Bitmap bitmap;
ImageView imageView;
String img_name, realPath;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    cntx=this;
    btnLoad=(Button) findViewById(R.id.btn_open);
    btnLoad.setOnClickListener(this);
    btnDetFace=(Button) findViewById(R.id.detection);
    btnDetFace.setOnClickListener(this);
}

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

@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.
    int id = item.getItemId();

    if (id == R.id.action_settings) {
        Intent dbmanager = new Intent(this,AndroidDatabaseManager.class);
         startActivity(dbmanager);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_open:
            Intent intent = new Intent();
            intent.setType("image/* video/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(intent, PICK_IMAGE_REQUEST);
            break;
        case R.id.detection:
            if(bitmap == null){
                Toast.makeText(MainActivity.this, "bitmap == null",
                        Toast.LENGTH_LONG).show();
            }
            else{
                detectFace();
                Toast.makeText(MainActivity.this,"Done",
                        Toast.LENGTH_LONG).show();
            }
            break;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {

        Uri uri = data.getData();
        try {
            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            imageView = (ImageView) findViewById(R.id.imageView);
            //compressImage(uri);
          //  imageView.setImageBitmap(bitmap);


            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            int width = size.x;
            int height = size.y;


            // SDK < API11
            if (Build.VERSION.SDK_INT < 11)
                realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(this, data.getData());

                // SDK >= 11 && SDK < 19
            else if (Build.VERSION.SDK_INT < 19)
                realPath = RealPathUtil.getRealPathFromURI_API11to18(this, data.getData());

                // SDK > 19 (Android 4.4)
            else
                realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());

            imageView.setImageBitmap(ImageResizer
                    .decodeSampledBitmapFromFile(realPath, width, height));

            img_name=realPath.substring(realPath.lastIndexOf("/")+1);
            count = ++count;

            if (count == 1) {
                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+5:30"));
                Date currentLocalTime = cal.getTime();
                DateFormat date = new SimpleDateFormat("hh:mm:ss");
                date.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
                String localTime = date.format(currentLocalTime);
                open_time = localTime;
            }
            else if (count > 1) {
                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+5:30"));
                Date currentLocalTime = cal.getTime();
                DateFormat date = new SimpleDateFormat("hh:mm:ss");
                date.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
                String localTime = date.format(currentLocalTime);
                close_time = localTime;
                Log.d("Insert: ", "Inserting ..");
                db.addTime(new Time(img_name,open_time, close_time));
                open_time = localTime;
                Log.d("Reading: ", "Reading all contacts..");
                List<Time> time = db.getAllData();

                for (Time t : time) {
                    String log = "Start time: " + t.getStartTime() + " ,End Time: " + t.getEndTime();
                    // Writing Time to log
                    Log.d("Time: ", log);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private void detectFace(){

    //Create a Paint object for drawing with
    Paint myRectPaint = new Paint();
    myRectPaint.setStrokeWidth(5);
    myRectPaint.setColor(Color.RED);
    myRectPaint.setStyle(Paint.Style.STROKE);

    //Create a Canvas object for drawing on
    Bitmap tempBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565);
    Canvas tempCanvas = new Canvas(tempBitmap);
    tempCanvas.drawBitmap(bitmap, 0, 0, null);

    //Detect the Faces
    FaceDetector faceDetector = new FaceDetector.Builder(getApplicationContext()).build();

    //!!!
    //Cannot resolve method setTrackingEnabled(boolean)
    //skip for now
    //faceDetector.setTrackingEnabled(false);

    Frame frame = new Frame.Builder().setBitmap(bitmap).build();

    SparseArray<Face> faces = faceDetector.detect(frame);

    //Draw Rectangles on the Faces
    for(int i=0; i<faces.size(); i++) {
        Face thisFace = faces.valueAt(i);
        float x1 = thisFace.getPosition().x;
        float y1 = thisFace.getPosition().y;
        float x2 = x1 + thisFace.getWidth();
        float y2 = y1 + thisFace.getHeight();
        tempCanvas.drawRoundRect(new RectF(x1, y1, x2, y2), 2, 2, myRectPaint);
    }
    imageView.setImageDrawable(new BitmapDrawable(getResources(),tempBitmap));
}
    }

3 个答案:

答案 0 :(得分:1)

在清单文件应用程序标记

中设置以下代码

机器人:largeHeap =&#34;真&#34;

答案 1 :(得分:0)

最好使用位图压缩功能压缩图像大小

tempBitmap.compress(Bitmap.CompressFormat.JPEG,70,FileName);

您可以根据需要调整压缩值。

答案 2 :(得分:0)

http://developer.android.com/training/displaying-bitmaps/index.html

您必须使用Android为此情况提供的Recycleimageview。您可以在显示时压缩位图..请查看您的问题将解决的给定链接implment。

并且android:largeHeap =“true”支持从Android 3.0到最新版本它不支持2.3版本,这不是解决方案。如果要正确修复问题,可以使用recycleimage。