2017-02-18 17 views
8

Tôi đang thử một số thao tác hình ảnh đơn giản trên một hình ảnh ở đầu một activity trong một số ImageView, có chiều cao trung bình là 200dp và khớp với chiều rộng của bố mẹ.Android - Các vấn đề về kéo và cắt

tôi đã thực hiện một lớp tùy chỉnh onTouchListener, mà tạo ra một matrix và chuyển hình ảnh trong ImageView

Kéo:

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

này hoạt động hoàn hảo, nó kéo hình ảnh trên y trục chỉ. Nhưng khi người dùng phát hành, tôi muốn hình ảnh cắt xuống các giới hạn của khu vực có thể nhìn thấy ImageView.

Crop:

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; 

vụ này sẽ cắt hình ảnh với kích thước phù hợp, nhưng chỉ từ phía trên cùng của nền của ImageView không phải là ranh giới nhìn thấy được. Với cuộc gọi tới hàm lớp BitmapcreateBitmap(int x, int y, int width, int height) giả định duy nhất của tôi là view.getTop() là làm cho nó bắt đầu ở trên cùng.

Vì vậy, câu hỏi của tôi là: Làm cách nào tôi có thể tính toán sự khác biệt giữa đầu giới hạn chế độ xem hiển thị và ranh giới nền/ma trận?

The dark blue area is the ImageView

Lưu ý: Các hình ảnh sẽ hiển thị một hình ảnh (màu xanh) mà nằm ở phía trên cùng của một hoạt động (cyan tìm kiếm khu vực chỉ là những nền ranh giới vô hình của ImageView, không phải là hoạt động)

Tôi muốn nhấn mạnh rằng tôi không muốn sử dụng bất kỳ thư viện của bên thứ ba nào để đạt được điều này.

Tôi sẵn sàng cung cấp mã bổ sung, nếu cần thiết.

Cập nhật:

Full onTouch phương pháp:

@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 
} 
+0

trong màn hình của bạn, bất kỳ bitmap nào bạn đặt trong nền trong toàn màn hình hoặc bạn đặt chiều cao bất kỳ, tôi biết bạn đã đặt 200dp nhưng tôi nghĩ rằng vùng hiển thị của hình ảnh sẽ bị cắt khi nhấp vào nút, vì vậy nếu bạn cung cấp thông tin màn hình của bạn với hình ảnh thực tế sau đó tôi sẽ giúp bạn .. –

+0

Hình ảnh bên trong hình ảnh sẽ bị cắt thành chiều rộng của màn hình và duy trì chiều cao dựa trên nó bị cắt (cắt xén bình thường), sau đó người dùng có thể kéo càng nhiều không gian, chiều cao của hình ảnh ban đầu cung cấp, nó sẽ là bất kỳ hình ảnh nào (tối thiểu phù hợp với chiều rộng của màn hình). Điều duy nhất được cố định trong này, là chiều cao của chính bản thân bộ nhớ ảo, kích thước ma trận là động, có nghĩa là khoảng cách giữa đầu ma trận và đầu tưởng tượng cũng là động –

Trả lời

0

Để tính chiều cao gốc của hoạt động, chúng ta có thể sử dụng

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

hoặc bạn có thể sử dụng số liệu hiển thị như

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

Hoặc thêm người nghe bố cục toàn cầu

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 
} 

});

+0

Vui lòng đọc lại câu hỏi. Tôi đang tìm các ranh giới giữa khu vực ImageView nhìn thấy được (màu xanh) (và giá trị của các ranh giới của phần trên cùng của vùng hiển thị đó lên trên cùng của ranh giới nền/ma trận (lục lam)). Sẽ có rất nhiều tiện ích con trong Hoạt động bên dưới ImageView để nhận được chiều cao của hoạt động là thừa. –

0

Mã thiếu ngữ cảnh nhưng tôi giả định rằng khi người dùng bắt đầu kéo bạn tạo savedMatrixstart điểm mới và cập nhật chúng mỗi lần bậtTouchListener được gọi hoặc cách khác, tôi không hiểu mã của bạn hoạt động như thế nào.

Nếu có nghĩa là bạn thực sự có bản dịch bạn cần trong số savedMatrix, vậy tại sao bạn không nhận được nó ngay từ đó? Tôi nghĩ rằng những gì bạn cần là một cái gì đó giống như

int top = savedMatrix.getValues()[Matrix.MTRANS_Y] 

tôi đã không kiểm tra nó và không biết cấu trúc bên trong của Matrix cũng đủ, vì vậy bạn có thể cần phải đảo ngược dấu hiệu của top.

Sidenote: Không rõ lý do tại sao trong số matrix.postTranslate(v.getX(), event.getY() - start.y); bạn vượt qua v.getX() tại đó. Có lẽ nó hoạt động OK chỉ vì v.getX() luôn luôn là 0 trong kịch bản của bạn.

Các vấn đề liên quan