如何防止For循环继续循环,直到循环内调用的方法完成?

时间:2020-06-05 00:22:17

标签: java android firebase face-detection firebase-mlkit

我正在尝试使用rect值从原始捕获的图像中裁剪出面部,以识别目标区域并创建仅面部检测区域的位图。这有效:)

问题是:

当我的图像具有一个以上的面孔时,onSuccess方法中的for循环会在警报对话框onClick()完成之前循环调用,该警报对话框用于为每个裁剪的面部文件名输入用户输入。调用警报对话框的onClick(OK)方法后,将触发用于保存每个面孔的代码。

该代码当前仅保存一个裁剪的面孔,在单独的警报对话框中可以正确处理不同的用户输入,但仅保存的最后一个面孔。

我认为,在触发警报对话框之后,但在用户完成输入并为每个面孔进行保存之前,for循环仍在继续循环。因此,当调用save方法时,它只会保存面孔列表中的最后一个对象。

关于如何改进此代码的任何建议?

 @Override
            public void onImage(CameraKitImage cameraKitImage) {
                capturedImage = cameraKitImage.getBitmap();
                capturedImage = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false);
                cameraView.stop();

                processFaceDetection(capturedImage);
            }




public void processFaceDetection(final Bitmap bitmap) {
        FirebaseVisionImage visionImage = FirebaseVisionImage.fromBitmap(bitmap);

        FirebaseVisionFaceDetectorOptions detectorOptions  = new FirebaseVisionFaceDetectorOptions.Builder()
                .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
                .setLandmarkMode(FirebaseVisionFaceDetectorOptions.NO_LANDMARKS)
                .setClassificationMode(FirebaseVisionFaceDetectorOptions.NO_CLASSIFICATIONS)
                .setMinFaceSize(0.15f)
                .enableTracking()
                .build();

        FirebaseVisionFaceDetector detector = FirebaseVision.getInstance().getVisionFaceDetector(detectorOptions);

        detector.detectInImage(visionImage).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
            @Override
            public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {

                listSize = firebaseVisionFaces.size();
                Bitmap originalCapture = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false);//scaled bitmap created from captured image
                saveImageOriginal(originalCapture);

                //for (FirebaseVisionFace face : firebaseVisionFaces) {
                for ( i = 0; i < firebaseVisionFaces.size(); i++){
                    FirebaseVisionFace face = firebaseVisionFaces.get(i);
                    Rect rect = face.getBoundingBox();
                    faceCrop = Bitmap.createBitmap(originalCapture, rect.left, rect.top, rect.width(), rect.height());//face cropped using rect values
                    RectOverlay rectOverlay = new RectOverlay(graphicOverlay, rect);
                    graphicOverlay.add(rectOverlay);//draw box around face

                    showAddItemDialog(Camera.CurrentContext); //prompt for name, save cropped face

                }

            }
        });
    }

 private void showAddItemDialog(Context c) {
        final EditText inputName = new EditText(c);
        AlertDialog dialog = new AlertDialog.Builder(c)
                .setTitle("Input Person's Name" + i)
                .setMessage("Format: LastName, FirstName")
                .setView(inputName)
                .setPositiveButton("Add", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        nameIn = String.valueOf(inputName.getText());
                        try {
                             saveImage(faceCrop);  //give read write permission



                        }catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
                })
                .setNegativeButton("Cancel", null)
                .create();
        dialog.show();
    }

public String saveImage(Bitmap croppedFace) {
        String eventFaces, event;
        event = "/Summer Event 2020";
        eventFaces = "/Event_Faces";

        final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        croppedFace.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
        final File facesDirectory = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + event + eventFaces); //crop

        if (!facesDirectory.exists()) {
            Log.d("directory SAVING", "" + facesDirectory.mkdirs());
            facesDirectory.mkdirs();
        }
        try {
            croppedFile = new File(facesDirectory, nameIn + ".jpg");
            croppedFile.createNewFile();
            FileOutputStream fo = new FileOutputStream(croppedFile);
            fo.write(bytes.toByteArray());
            MediaScannerConnection.scanFile(Camera.CurrentContext, new String[]{croppedFile.getPath()}, new String[]{"image/jpeg"}, null);
            fo.close();
            Log.d("TAG", "File Saved::--->" + croppedFile.getAbsolutePath());
            Toast.makeText(Camera.this, nameIn + "  " + "i" + i + " list" + listSize + " " + "Face Cropped and Saved to -> " + croppedFile.getPath(), Toast.LENGTH_SHORT).show();

            return croppedFile.getAbsolutePath();

        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return "";


    }//end of save image











1 个答案:

答案 0 :(得分:0)

如果有人遇到相同类型的问题,我将for循环中的代码分为两个单独的循环,并在用户输入(键盘输入)中将一个标志合并到AlertDialog中。一旦该标志为true,则在AlertDialog用户输入之后,现在将满足第二个for循环的条件。

希望这会有所帮助。

相关问题