如何在PhotoView中按比例缩放(缩放和移动)位图至x,y坐标?

3

我使用了https://github.com/chrisbanes/PhotoView库。

一开始我有一个位图和位于位图上的x、y坐标。

如何缩放和放大图像以适应位图的x、y坐标?

int bitmapWidth = bitmap.getWidth();//2418
int bitmapHeight = bitmap.getHeight();//1889
float x = 1209f;
float y = 944f;

float targetScale = 4f;    
attacher.setScale(targetScale, x,y, false);//it doesnt work

比例尺为1f enter image description here

比例尺为4f,我想编程移动中心点到x、y坐标处 enter image description here


那个 x,y 点是用来做什么的? - pskink
@pskink 位图上点的坐标 - NickUnuchek
好的,举个例子,如果是100和200,你想要在视图中将它居中吗?或者你想要它在视图的某个角落?也许可以发一张图片来描述你想要实现的效果? - pskink
@pskink,没错,我想要缩放并移动到以此x,y点为中心的视图。 - NickUnuchek
@pskink更新了问题,在第一个scale = 1f,在第二个scale = 4f,我想通过编程将中心移动到x,y坐标。 - NickUnuchek
嗨,我在这里看到了你的帖子 https://github.com/chrisbanes/PhotoView/issues/585 ,@aslansari 的答案是正确的,但是你有没有找到如何移动缩放区域中心的内容? - Zenocode
3个回答

1

我曾经面临同样的问题,但最终解决了它。

为了实现这一点,我尝试了很多方法。首先,您需要将您的坐标转换为 PhotoView

int bitmapWidth = bitmap.getWidth();//2418
int bitmapHeight = bitmap.getHeight();//1889
float x = 1209f;
float y = 944f;

float focalX = x*photoView.getRight()/bitmap.getWidth();
float focalY = y*photoView.getBottom()/bitmap.getHeight();

float targetScale = 4f;
attacher.setScale(targetScale, focalX, focalY, false);

来源:GitHub aslansari

这个答案适用于缩放部分。当放大时,为了使您的对象中心在屏幕中心上进行编程移动,我做了这个。

var event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, focalX, focalY, 0)
mPhotoView.dispatchTouchEvent(event)

val centerImageX = showResultCoinDetectionPhotoView.displayRect.centerX()
val centerImageY = showResultCoinDetectionPhotoView.displayRect.centerY()

var event = event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, centerImageX, centerImageY, 0)
mPhotoView.dispatchTouchEvent(event)

如果你不需要缩放动画,那么你就不需要更多了。

如果你想使用动画

我已经找到问题所在,但还无法修复。以下是我的想法。

这不起作用,因为它在另一个线程中调用动画。

//PhotoViewAttacher.java
mImageView.post(new AnimatedZoomRunnable(getScale(), scale, focalX, focalY));

同时,我尝试模拟移动以将点重新居中于屏幕中心。

var event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, focalX, focalY, 0)
mPhotoView.dispatchTouchEvent(event)

val centerImageX = showResultCoinDetectionPhotoView.displayRect.centerX()
val centerImageY = showResultCoinDetectionPhotoView.displayRect.centerY()

var event = event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, centerImageX, centerImageY, 0)
mPhotoView.dispatchTouchEvent(event)

但是当代码的这部分被执行时,比例尺还没有完成,因此移动无法发生,因为图像是全尺寸的,我们无法拖动全尺寸的图像。

所以为了解决这个问题,我删除了动画。

mPhotoView.setScale(5f, focalX, focalY, false)

另一种解决方案可以使用回调或协程来进行缩放和同时进行移动,因为我们将处于顺序代码部分。但是 AnimatedZoomRunnable 在另一个线程中,所以我们将一直执行到:

if (animate) {
       mImageView.post(new AnimatedZoomRunnable(getScale(), scale, focalX, focalY));
}

并返回到协程的下一行。

所以实际上我没有更多的选择。也许可以放置一个按钮,使点能够居中于屏幕中央,就像在GoogleMap中一样,并在用户单击时执行“模拟拖动”?

或者有没有一种方法可以在AnimatedZoomRunnable完成时得到通知?

如果您发现了有趣的东西,请告诉我。


0
    var photoView=findViewById(R.id.photoView)
    var zoomBtn=findViewById(R.id.zoomBtn)
    zoomBtn.setOnClickListener {
        if (photoView.scale!=photoView.minimumScale)
             photoView.scale = photoView.minimumScale
        else photoView.scale = photoView.maximumScale
    }

通常情况下,如果答案包含代码的意图和解决问题的原因,而不会引入其他问题,那么这些答案会更有帮助。 - DCCoder
这里的主要代码只有一行 photoView.scale = photoView.maximumScale。其他的是监听器、条件等,所以我没有解释。 - Rizwan Ahmed

0

我找到了一种更简单的解决方案。它基于dispatchTouchEvent()方法。

public class YourActivity extends AppCompatActivity {

    private float mTapX;
    private float mTapY;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        mTapX = ev.getX();
        mTapY = ev.getY();
        return super.dispatchTouchEvent(ev);
    }

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

        PhotoView photoView = findViewById(R.id.photo_view);
        mPhotoView.setImageResource(R.drawable.pic1);
        mPhotoView.setOnPhotoTapListener((view, x, y) -> {
            mPhotoView.setScale(photoView.getMaximumScale(), mTapX, mTapY, true);
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接