Android - 拖动和裁剪问题

时间:2017-02-18 11:03:56

标签: android

我正在尝试对activityImageView顶部的图像进行一些简单的照片处理,其平均高度为200dp并与宽度相匹配它的父母。

我已经实施了一个自定义onTouchListener类,可以创建matrix并在ImageView

中翻译图片

case MotionEvent.ACTION_MOVE:
     if (mode == DRAG) {
        matrix.set(savedMatrix);
        matrix.postTranslate(v.getX(), event.getY() - start.y);
     }
     break;

这非常有效,它只拖动 y轴上的图像。但是当用户发布时,我希望图像裁剪到可见ImageView区域的边界。

农作物

case MotionEvent.ACTION_UP:
     if (mode == DRAG) {
        Bitmap bitmap = drawableToBitmap(view.getDrawable());
        Bitmap result = Bitmap.createBitmap(bitmap,view.getLeft(), view.getTop(), view.getWidth(), view.getHeight());
        view.setImageBitmap(result);
      }
      break;

这会将图像裁剪为正确的尺寸,但仅从图像视图的背景顶部而不是可见边界。通过调用Bitmap类函数createBitmap(int x, int y, int width, int height),我唯一的假设就是view.getTop()让它从顶部开始。

所以,我的问题是:我如何计算可见视图边界的顶部与背景/矩阵边界之间的差异?

The dark blue area is the ImageView

注意:图像显示位于活动顶部的图像(蓝色)(青色的区域只是ImageView的背景不可见边界,而不是活动)

我想强调一点,我不希望使用任何第三方库来实现这一目标。

如果需要,我非常愿意提供额外的代码。

更新

完整onTouch方法:

@Override
public boolean onTouch(View v, MotionEvent event) {
    ImageView view = (ImageView) v;
    // Dump touch event to log
    dumpEvent(event);

    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(v.getX(), event.getY());
            mode = DRAG;
            originalY.y = (int) event.getY();
            break;
        case MotionEvent.ACTION_UP:
             if (mode == DRAG) {
        Bitmap bitmap = drawableToBitmap(view.getDrawable());
        Bitmap result = Bitmap.createBitmap(bitmap,view.getLeft(), view.getTop(), view.getWidth(), view.getHeight());
        view.setImageBitmap(result);
      }
      break;
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                matrix.set(savedMatrix);
                matrix.postTranslate(v.getX(), event.getY() - start.y);
            }
            break;
    }
    view.setImageMatrix(matrix);
    return true; // indicate event was handled
}

2 个答案:

答案 0 :(得分:0)

要计算活动的根高度,我们可以使用

int height = this.getWindow().getDecorView().getHeight();

或者您可以将显示指标用作

DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;

或添加全局布局侦听器

ViewTreeObserver vtObserver = view.getViewTreeObserver();
vtObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
    // check if the view's height and/or width > 0
    // don't forget to remove the listener when done using removeOnGlobalLayoutListener
}

});

答案 1 :(得分:0)

代码缺少一些上下文,但我假设当用户开始拖动时,你创建新的dependencies { // core functionalities compile project(":core") testCompile project(":core") testCompile project(":core").sourceSets.test.output } savedMatrix点并在每次调用onTouchListener时更新它们,否则我不明白你的代码是如何工作的一点都不。

如果是这样,这意味着您实际上已经在start中获得了所需的翻译,那么为什么不从那里做到正确呢?我认为你需要的是像

savedMatrix

我没有检查它,也不太了解int top = savedMatrix.getValues()[Matrix.MTRANS_Y] 的内部结构,因此您可能需要反转Matrix的符号。

旁注:目前尚不清楚为什么在top通过matrix.postTranslate(v.getX(), event.getY() - start.y);。可能它工作正常只是因为你的场景中v.getX()始终为0。