无法将图像视图加载到位图Android抓取中

时间:2018-07-26 14:45:15

标签: android opencv image-processing android-bitmap

嗨,我正在尝试从开放的简历中实现抓取剪切算法。我从本地存储中选择图像,然后对其进行抓取剪切。问题是,当我在位图上调用设置图像位图时,在进行抓取剪切后,图像未加载到图像视图中。这是完整的代码。我实际上对open cv及其库并不十分熟悉,所以我发现它是从git hub获得的。其开放的cv 3.4.1

MainActivity:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (!OpenCVLoader.initDebug()) {
        Log.e(this.getClass().getSimpleName(), "  OpenCVLoader.initDebug(), not working.");
    } else {
        Log.d(this.getClass().getSimpleName(), "  OpenCVLoader.initDebug(), working.");
    }


    mImageView = findViewById(R.id.imgDisplay);
    dlg = new ProgressDialog(this);
    tl = new Point();
    br = new Point();
    if (!OpenCVLoader.initDebug()) {
        Log.i(TAG,"load successful");
    }
}

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main,menu);
    return true;
}




private void setPic() {
    // use to compress image
    int targetW = mImageView.getWidth();
    int targetH = mImageView.getHeight();

    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    mBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    mImageView.setImageBitmap(mBitmap);
    Log.i(TAG,"set pic here");

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_OPEN_IMAGE:
            if (resultCode == RESULT_OK) {
                Uri imgUri = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };

                // used to get file path from uri.
                Cursor cursor = getContentResolver().query(imgUri, filePathColumn,
                        null, null, null);
                cursor.moveToFirst();

                int colIndex = cursor.getColumnIndex(filePathColumn[0]);
                mCurrentPhotoPath = cursor.getString(colIndex);
                Log.i(TAG,mCurrentPhotoPath);
                cursor.close();
                setPic();
            }
            break;
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    switch (id) {
        case R.id.action_open_img:
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE )==
                    PackageManager.PERMISSION_GRANTED) {
                Intent getPictureIntent = new Intent(Intent.ACTION_GET_CONTENT);
                getPictureIntent.setType("image/*");
                Intent pickPictureIntent = new Intent(Intent.ACTION_PICK,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                Intent chooserIntent = Intent.createChooser(getPictureIntent, "Select Image");
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{
                        pickPictureIntent
                });
                startActivityForResult(chooserIntent, REQUEST_OPEN_IMAGE);
            } else {
                requestStoragePermission();
                Toast.makeText(MainActivity.this, "No permission?", Toast.LENGTH_SHORT).show();
            }
            return true;
        case R.id.action_choose_target:
            if (mCurrentPhotoPath != null)
                targetChose = false;
            mImageView.setOnTouchListener(new View.OnTouchListener() {

                //what happens when user touches the image
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // event.getAction() returns what type of action performed by the user
                    // ACTION_DOWN means make your finger touch the screen.
                    // ACTION_UP opposite
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        if (touchCount == 0) {
                            tl.x = event.getX();
                            tl.y = event.getY();

                            Log.i(TAG,"x " + tl.x + " y " + tl.y);
                            touchCount++;
                        }
                        else if (touchCount == 1) {
                            br.x = event.getX();
                            br.y = event.getY();
                            Log.i(TAG,"br.x " + br.x + " br.y " + br.y);
                            Paint rectPaint = new Paint();
                            rectPaint.setARGB(255, 255, 0, 0);
                            rectPaint.setStyle(Paint.Style.STROKE);
                            rectPaint.setStrokeWidth(3);
                            Bitmap tmpBm = Bitmap.createBitmap(mBitmap.getWidth(),
                                    mBitmap.getHeight(), Bitmap.Config.RGB_565);
                            Canvas tmpCanvas = new Canvas(tmpBm);

                            tmpCanvas.drawBitmap(mBitmap, 0, 0, null);
                            tl.x = tl.x * (float)tmpCanvas.getWidth() / v.getRight();
                            tl.y = tl.y * (float)tmpCanvas.getHeight() / v.getBottom();
                            br.x = br.x * (float)tmpCanvas.getWidth() / v.getRight();
                            br.y = br.y * (float)tmpCanvas.getHeight() / v.getBottom();
                            tmpCanvas.drawRect(new RectF((float) tl.x, (float) tl.y, (float) br.x, (float) br.y),
                                    rectPaint);
                            Log.i(TAG,"tl x: " + (float)tl.x + " tl.y " + (float)tl.y + " br.x " + (float)br.x + " br.y " + (float)br.y);
                            mImageView.setImageDrawable(new BitmapDrawable(getResources(), tmpBm));

                            targetChose = true;
                            touchCount = 0;
                            mImageView.setOnTouchListener(null);
                        }
                    }
                    return true;
                }
            });

            return true;
        case R.id.action_cut_image:
            if (mCurrentPhotoPath != null && targetChose) {
                new ProcessImageTask().execute();
                targetChose = false;
            }
            return true;
    }

    return super.onOptionsItemSelected(item);
}

private void requestStoragePermission() {
    ActivityCompat.requestPermissions(MainActivity.this,
            new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},STORAGE_PERMISSION_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == STORAGE_PERMISSION_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(MainActivity.this,"Permission Granted",Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(MainActivity.this,"permission denied",Toast.LENGTH_SHORT).show();
        }

    }
}

private class ProcessImageTask extends AsyncTask<Integer, Integer, Integer> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dlg.setMessage("Processing Image...");
        dlg.setCancelable(false);
        dlg.setIndeterminate(true);
        dlg.show();
    }

    @Override
    protected Integer doInBackground(Integer... params) {
        Mat img = Imgcodecs.imread(mCurrentPhotoPath);
        Mat background = new Mat(img.size(), CvType.CV_8UC3,
                new Scalar(255, 255, 255));
        Mat firstMask = new Mat();
        Mat bgModel = new Mat();
        Mat fgModel = new Mat();
        Mat mask;
        Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(Imgproc.GC_PR_FGD));
        Mat dst = new Mat();
        Rect rect = new Rect(tl, br);

        Imgproc.grabCut(img, firstMask, rect, bgModel, fgModel,
                5, Imgproc.GC_INIT_WITH_RECT);
        Log.i(TAG,"grab cut works here");
        Core.compare(firstMask, source, firstMask, Core.CMP_EQ);

        Mat foreground = new Mat(img.size(), CvType.CV_8UC3,
                new Scalar(255, 255, 255));
        img.copyTo(foreground, firstMask);

        Scalar color = new Scalar(255, 0, 0, 255);
        Imgproc.rectangle(img, tl, br, color);

        Mat tmp = new Mat();
        Imgproc.resize(background, tmp, img.size());
        background = tmp;
        mask = new Mat(foreground.size(), CvType.CV_8UC1,
                new Scalar(255, 255, 255));

        Imgproc.cvtColor(foreground, mask, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(mask, mask, 254, 255, Imgproc.THRESH_BINARY_INV);
        System.out.println();
        Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0));
        background.copyTo(dst);

        background.setTo(vals, mask);

        Core.add(background, foreground, dst, mask);

        firstMask.release();
        source.release();
        bgModel.release();
        fgModel.release();
        vals.release();

        Imgcodecs.imwrite(mCurrentPhotoPath + ".png", dst);
        Log.i(TAG,"grabcut done");

        return 0;
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        Log.i(TAG,"postExecute");

        Bitmap jpg = BitmapFactory
                .decodeFile(mCurrentPhotoPath + ".png");
        boolean isNull = jpg == null;
        Log.i(TAG,"bitmap is " + isNull);

        mImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        mImageView.setAdjustViewBounds(true);
        mImageView.setPadding(2, 2, 2, 2);
        mImageView.setImageBitmap(jpg);
        mImageView.invalidate();

        Log.i(TAG,"hmmm? its done ");
        dlg.dismiss();
    }
}

当我尝试将抓取切割的位图设置为图像视图时,在后执行方法中出现问题。根据上述日志标签,位图不为null。我似乎在日志中也找不到任何错误。

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ImageView
    android:id="@+id/imgDisplay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true" />
</RelativeLayout>

我意识到我得到了一张很小的图片,有点像一个坏点,因此为什么位图不为空。但是,在具有开放cv 2.x版本的Windows com上运行此代码可以使我获得截取的图像。

0 个答案:

没有答案