【问题标题】:direct2d image viewer How to convert screen coordinates to image coordinates?direct2d image viewer 如何将屏幕坐标转换为图像坐标?
【发布时间】:2013-12-01 21:34:29
【问题描述】:

我试图弄清楚如何将鼠标位置(屏幕坐标)转换为在 direct2d 表面上绘制的底层转换图像上的对应点。 这里的代码应该被认为是伪代码,因为我使用了一个修改过的 c++/CLI 包装器,用于 c# 的 direct2d,除了我自己的项目之外,你将无法在任何东西中编译它。

Render()
{
    //The transform matrix combines a rotation, followed by a scaling then a translation
    renderTarget.Transform = _rotate * _scale * _translate;
    RectF imageBounds = new RectF(0, 0, _imageSize.Width, _imageSize.Height);
    renderTarget.DrawBitmap(this._image, imageBounds, 1, BitmapInterpolationMode.Linear);
}
Zoom(float zoomfactor, PointF mousepos)
{
    //mousePos is in screen coordinates. I need to convert it to image coordinates.
    Matrix3x2 t = _translate.Invert();
    Matrix3x2 s = _scale.Invert();
    Matrix3x2 r = _rotate.Invert();
    PointF center = (t * s * r).TransformPoint(mousePos); 
    _scale = Matrix3x2.Scale(zoomfactor, zoomfactor, center);    
}

这是不正确的,当缩放因子平滑增加或减少时,缩放中心开始疯狂移动,即使鼠标指针在客户端表面的中心不动,生成的缩放功能也不平滑并且闪烁很多。我尝试了所有我能想到但无法弄清楚的组合。

如果我将缩放中心点设置为 (imagewidth/2, imageheight/2),则生成的缩放是平滑的,但始终以图像中心为中心,所以我很确定闪烁不是由于其他原因程序的错误部分。

谢谢。

【问题讨论】:

  • 尝试将t * s * r 替换为r * s * t。并确保屏幕点位于客户端坐标中,并考虑到 (可能是自定义的) DPI。
  • 我已经尝试过了,闪烁更严重,mousepos的东西只是为了更好地说明我的目标;只要我没有可靠的解决方案,我就将其固定在客户中心进行测试。

标签: matrix transform direct2d


【解决方案1】:

我终于做对了

这给了我以客户端中心为中心的完美平滑(增量?,相对?)缩放 (我放弃了鼠标位置的想法,因为我想使用鼠标移动输入来驱动缩放)

     protected float zoomf
    {
        get
        {
            //extract scale factor from scale matrix
            return (float)Math.Sqrt((double)((_scale.M11 * _scale.M11) 
                                              + (_scale.M21 * _scale.M21)));
        }
    }

    public void Zoom(float factor)
    {

        factor = Math.Min(zoomf, 1) * 0.006f * factor;
        factor += 1;

        Matrix3x2 t = _translation;
        t.Invert();
        PointF center = t.TransformPoint(_clientCenter);


        Matrix3x2 m = Matrix3x2.Scale(new SizeF(factor, factor), center);
        _scale = _scale * m;
        Invalidate();
    }

【讨论】:

    【解决方案2】:

    Step1: 将 android:scaleType="matrix" 放入 ImageView XML 文件中 第 2 步: 将屏幕触摸点转换为矩阵值。 第 3 步: 将每个矩阵值与屏幕密度参数相除以 在所有屏幕中获取相同的坐标值。

    **XML**
    <ImageView
      android:id="@+id/myImage"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:scaleType="matrix"
      android:src="@drawable/ga"/>
    
    **JAVA**
     @Override
      public boolean onTouchEvent(MotionEvent event) {
        float[] point = new float[]{event.getX(), event.getY()};
        Matrix inverse = new Matrix();
        getImageMatrix().invert(inverse);
        inverse.mapPoints(point);
        float density = getResources().getDisplayMetrics().density;
        int[] imagePointArray = new int[2];
        imagePointArray[0] = (int) (point[0] / density);
        imagePointArray[1] = (int) (point[1] / density);
        Rect rect = new Rect( imagePointArray[0] - 20, imagePointArray[1]  - 20,  imagePointArray[0] + 20, imagePointArray[1]  + 20);//20 is the offset value near to the touch point
            boolean b = rect.contains(267, 40);//267,40 are the predefine image coordiantes
            Log.e("Touch inside ", b + "");
        return true;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多