簡體   English   中英

Android - 在上傳的 bitmap 圖像上繪制矩形

[英]Android - draw rectangle on uploaded bitmap image

我正在使用 tflite model,我正在嘗試在檢測到 object 的圖像上繪制 RectF。

這是我的 CameraActivity.java class,我在其中檢測到 object。

predictBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                img = Bitmap.createScaledBitmap(img, 128, 128, true);

                try {
                    DrawView drawView = new DrawView(getApplicationContext());
                    Android model = Android.newInstance(getApplicationContext());

                    // Creates inputs for reference.
                    TensorImage image = TensorImage.fromBitmap(img);


                    // Runs model inference and gets result.
                    Android.Outputs outputs = model.process(image);
                    Android.DetectionResult detectionResult = outputs.getDetectionResultList().get(0);

                    // Gets result from DetectionResult.
                    float score = detectionResult.getScoreAsFloat();
                    RectF location = detectionResult.getLocationAsRectF();
                    String category = detectionResult.getCategoryAsString();

                    // Releases model resources if no longer used.

                    mCanvas.drawBoundingBox();
                    model.close();
                    // here we will print out the results of the object to text views based on the image that is inputted by the user
                    // we print out object type and its accuracy score
                    mCanvasView.drawRect();
                    objecttv.setText(category);
                    scoretv.setText(Float.toString(score));

                } catch (IOException e) {
                    // TODO Handle the exception
                }

            }
        }
        );

這是我的 DrawView.java class

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class DrawView extends View {
    Paint boxPaint;
    public static Canvas mCanvas;

    public DrawView(Context context) {
        super(context);
        boxPaint = new Paint();
    }

    public void drawBoundingBox() {
        // Refresh the view by calling onDraw function
        invalidate();
    }

    
    public void onDraw(Canvas canvas, AttributeSet attrs) {
        // Draw what you want
        boxPaint.setColor(Color.RED);
        boxPaint.setAlpha(200);
        boxPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(location, boxPaint);
    }
}

在我的 activity_camera.xml 中,我添加了 drawview 以匹配我正在上傳的圖像。

  <com.example.aPROJECT.DrawView
        android:id="@+id/canvasView"
        android:layout_width="281dp"
        android:layout_height="324dp"
        android:layout_marginTop="30dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
         />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="281dp"
        android:layout_height="324dp"
        android:layout_marginTop="30dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/ic_menu_gallery"
        tools:ignore="ImageContrastCheck" />

在 CameraActivity.java 中,在線mCanvas.drawBoundingBox(); 它無法從 DrawView.java class 訪問 mCanvas。

線上mCanvasView.drawRect(); 它無法解析符號。

我在這里錯過了什么?

有幾個問題:

  • 如果你想在 Java 中訪問 class 之外的 static 字段,你需要像這樣指定 class 名稱DrawView.mCanvas或者使用 static 導入(添加一行

    import static /*class.package.name.here.*/DrawView.mCanvas;

    在 class 聲明上面然后你可以直接使用 mCanvas)

  • drawBoundingBox() 是 DrawView 中的一個方法,而不是 canvas 所以正確的調用方式是 drawView.drawBoundingBox()

  • 即使 class 可以編譯,在調用 drawRoundingBox() 時也會出現 NullPointerException,因為 mCanvas 尚未在 DrawView 中初始化

  • View 中的 canvas 只是一個臨時變量,作為 onDraw 的參數,用於在該時刻(每一幀)創建用戶界面,並不意味着在該方法之外使用,因為它指向/引用視頻 memory 緩沖區這是不斷變化的

你應該做的是為你試圖繪制和使用它的 Bitmap 創建一個 Canvas(你不需要視圖來改變位圖):

//if img is the bitmap you want to draw on
Canvas c = new Canvas(img); //before createScaledBitmap()
drawBoundingBox(c);// move onDraw code to drawBoundingBox()
                   // and the latter method to CameraActivity

//Should you need to get the bitmap screenshot of a view simply draw it:
Bitmap vscr = Bitmap.createBitmap(yourView.getWidth(), yourView.getHeight(), Bitmap.Config.ARGB_8888);
//ensure the view was added to the layout (measured) so that its width and height are greater than  zero when you create the bitmap
yourView.draw(vscr);

例子

public class CameraActivity extends ActivityCompat {


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...

        predictBtn.setOnClickListener(new View.OnClickListener()  {

        @Override
        public void onClick(View v) {

            img = Bitmap.createScaledBitmap(img, 128, 128, true);

            try {
                //DrawView drawView = new DrawView(getApplicationContext());
                Android model = Android.newInstance(getApplicationContext());

                // Creates inputs for reference.
                TensorImage image = TensorImage.fromBitmap(img);


                // Runs model inference and gets result.
                Android.Outputs outputs = model.process(image);
                Android.DetectionResult detectionResult = outputs.getDetectionResultList().get(0);

                // Gets result from DetectionResult.
                float score = detectionResult.getScoreAsFloat();
                RectF location = detectionResult.getLocationAsRectF();
                String category = detectionResult.getCategoryAsString();

                // Releases model resources if no longer used.
                Canvas canvas = new Canvas(img);

                drawBoundingBox(canvas, location);
                model.close();
                // here we will print out the results of the object to text views based on the image that is inputted by the user
                // we print out object type and its accuracy score
                mCanvasView.drawRect();
                objecttv.setText(category);
                scoretv.setText(Float.toString(score));

            } catch (IOException e) {
                // TODO Handle the exception
            }

        }
    });

    } //onCreate

    void drawBoundingBox(Canvas canvas, RectF location) {
        // Draw what you want
        Paint boxPaint = new Paint();
        boxPaint.setColor(Color.RED);
        boxPaint.setAlpha(200);
        boxPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(location, boxPaint);
   }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM