【问题标题】:Android getImageMatrix() returns wrong MatrixAndroid getImageMatrix() 返回错误的矩阵
【发布时间】:2021-07-05 09:46:44
【问题描述】:

我有一个实现 onPictureTaken 的 CameraActivity。在这种方法中,我将图像保存到公共 DCIM 文件夹并将 Intent 发送到另一个 PicturePrevActivity。 这里是发件人代码:

public void onPictureTaken(byte[] data, Camera camera) {
           
            Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
            Matrix rotateMatrix = new Matrix();
            rotateMatrix.postRotate(90);
            Bitmap rotatedBitmap = Bitmap.createBitmap(bmp, 0, 0,  bmp.getWidth(), bmp.getHeight(), rotateMatrix, false);

            String savefilename = saveBitmapPublic(rotatedBitmap,Environment.DIRECTORY_DCIM,"test.jpg");
            if(savefilename != null) {
                Intent intent = new Intent(CameraActivity.this,PicturePrevActivity.class);
                intent.putExtra("picture", savefilename);
                startActivity(intent);
          }  }

这是在 OnCreate() 中接收 PicturePrevActivty 的代码:

if(getIntent().hasExtra("picture")) {

        try {             
         
            mBitmap = BitmapFactory.decodeFile(getIntent().getStringExtra("picture"));
            mSelectionImageView.setImageBitmap(mMyOpenCVWrapper.getResizedBitmap(mBitmap, MAX_HEIGHT));
            List<PointF> points = mMyOpenCVWrapper.findPoints(mBitmap);
            mSelectionImageView.setPoints(points);


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

    }

为了解释,findPoints 方法在 mBitmap 上检测每个 OpenCV 的边缘,并使用此函数将这些点从 mBitmap 转换为 mSelectionImageView 的视点:

 private PointF mapPointToMatrix(PointF point) {
    
    float[] points = new float[] { point.x, point.y };
    mSelectionImageView.getImageMatrix().mapPoints(points);   //this line is the problem, the matrix differs. 
    if (points.length > 1) {
      
        return new PointF(points[0], points[1]);
    } else {
        return null;
    }
}

如果我在接收 PicturePrevActivty 中单击按钮后开始此操作,则生成的 Rect 是正确的。 但是当我在接收 PicturePrevActivity 的 OnCreate、OnStart 或 OnResume 过程中启动这些操作时,生成的 Rect 太小了。

这里很有趣,如果我将此代码复制到 onCreateOptionsMenu() 方法,它就像一个魅力:

  @Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main_menu, menu);

    if(getIntent().hasExtra("picture")) {

        try {
                
             mBitmap = BitmapFactory.decodeFile(getIntent().getStringExtra("picture"));
           
            mSelectionImageView.setImageBitmap(mMyOpenCVWrapper.getResizedBitmap(mBitmap, MAX_HEIGHT));
            List<PointF> points = mMyOpenCVWrapper.findPoints(mBitmap);
            mSelectionImageView.setPoints(points);

        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(PicturePrevActivity.this,"Error reading picture",Toast.LENGTH_LONG).show();
        }

    }

    return true;
}

正如我在代码中所标记的,getImageMatrix() 方法是此构造中的问题。它应该交付 矩阵{[1.856, 0.0, 12.0][0.0, 1.856, 0.0][0.0, 0.0, 1.0]},但它提供 矩阵{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]} 如果我在 OnCreate、OnStart 或 OnResume 中调用它。只有在 onCreateOptionsMenu() 中使用时才有效。

有人可以帮我吗?为什么在 onCreateOptionsMenu() 中调用时只返回正确的点 getImageMatrix()?我的错是什么?

编辑 2021-07-16:没有人给我建议吗?

提前非常感谢! 最好的祝福, 麦克

【问题讨论】:

    标签: android opencv matrix imageview point


    【解决方案1】:

    官方文档是这样说的:

    返回视图的可选矩阵。这在绘制时应用于视图的可绘制对象。如果没有矩阵,此方法将返回一个单位矩阵。不要更改此矩阵,而是复制一份。如果您想将不同的矩阵应用于可绘制对象,请务必调用 setImageMatrix()。

    您在 onCreate / onResume / onStart 中获得了一个身份矩阵,因为该矩阵尚未“准备好”。我想在尝试获取矩阵之前,您必须找到一种方法来知道矩阵何时“准备就绪”。

    我建议使用 GlidePicasso 库来加载您的位图图像,如下所示:

    Picasso.get().load(new File(getIntent().getStringExtra("picture")))
                 .into(mSelectionImageView, new Callback() {
                       @Override
                       public void onSuccess(){
                           // image is ready
                       }
    
                       @Override
                       public void onError(Exception ex){
                           // image loading failed
                       }
                 });
    

    注意:Callback 参数是一个强引用,将防止您的 Activity 或 Fragment 被垃圾收集。如果您使用此方法,强烈建议您调用相邻的 Picasso.cancelRequest(android.widget.ImageView) 调用以防止临时泄漏。

    【讨论】:

      猜你喜欢
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 2021-05-11
      • 2018-02-17
      • 2016-01-01
      • 2014-09-18
      相关资源
      最近更新 更多