我想在ImageView
上添加一个矩形边框,允许用户从8个方向更改它的大小,以便为裁剪目的提供预览。
我可以通过哪种方式实现最佳目的,定义自定义ImageView
并添加代码以绘制矩形或将ImageView
添加到SurfaceView
?
这是我的代码,我可以使用它在我的图像周围绘制一个矩形:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class CustomCropImageView extends ImageView implements View.OnTouchListener{
// Bitmap to draw.
Bitmap myBitmap;
// Fundamental attributes.
int xPos, yPos;
int originWidth, originHeight;
int widthImg, heightImg;
int xCrop, yCrop;
int cropWidth, cropHeight;
GestureDetector myGesture;
public CustomCropImageView(Context context){
super(context);
xPos = yPos = xCrop = yCrop = 0;
// setOnTouchListener(this);
}
public CustomCropImageView(Context context, AttributeSet attSet){
super(context, attSet);
xPos = yPos = xCrop = yCrop = 0;
// setOnTouchListener(this);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if(drawable == null)
return;
if(originWidth == 0 && originHeight == 0){
Bitmap tmp = ((BitmapDrawable)drawable).getBitmap();
myBitmap = tmp.copy(Bitmap.Config.ARGB_8888, true);
originWidth = myBitmap.getWidth();
originHeight = myBitmap.getHeight();
Integer[] myDWAndH = getScreenWidthAndHeight();
widthImg = cropWidth = myDWAndH[0];
heightImg = cropHeight = (int)((float)myDWAndH[0]*((float)originHeight / (float)originWidth));
yPos = yCrop = (myDWAndH[1] - heightImg) / 2;
myBitmap = Bitmap.createScaledBitmap(myBitmap, widthImg, heightImg, false);
}
Paint myPaint = new Paint();
canvas.drawBitmap(myBitmap, xPos, yPos, myPaint);
drawAnchorRectangle(canvas);
}
void drawAnchorRectangle(Canvas canvas){
// Anchor rectangle.
Paint myPaint = new Paint();
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setColor(getContext().getResources().getColor(R.color.ImgVBorder));
myPaint.setStrokeWidth(5);
Rect myRect = new Rect(xCrop, yCrop, cropWidth, yCrop + cropHeight);
canvas.drawRect(myRect, myPaint);
// Anchor point.
myPaint.setStyle(Paint.Style.FILL);
myPaint.setColor(getContext().getResources().getColor(R.color.ImgVAnchorPoint));
myPaint.setStrokeWidth(3);
int anchorPointW = 10;
int halfAnchorPointW = anchorPointW / 2;
/*
// Top left.
Rect anchorPoint = new Rect(xCrop + cropWidth - halfAnchorPointW, yCrop - halfAnchorPointW,
anchorPointW, yCrop + halfAnchorPointW);
canvas.drawRect(anchorPoint, myPaint);
// Top right.
anchorPoint.set(xCrop + cropWidth - halfAnchorPointW, yCrop - halfAnchorPointW,
anchorPointW, yCrop + halfAnchorPointW);
canvas.drawRect(anchorPoint, myPaint);
*/
}
Integer[] getScreenWidthAndHeight(){
DisplayMetrics dMetrics = new DisplayMetrics();
((MainActivity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(dMetrics);
Integer[] myResult = new Integer[2];
myResult[0] = dMetrics.widthPixels - 40;
myResult[1] = dMetrics.heightPixels;
return myResult;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
final String TAG = "!!!123";
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "Action was DOWN");
return true;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "Action was MOVE");
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "Action was UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.d(TAG, "Action was CANCEL");
break;
case MotionEvent.ACTION_OUTSIDE:
Log.d(TAG, "Movement occurred outside bounds of current screen element");
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return super.onTouchEvent(event);
}
}
答案 0 :(得分:0)
这里是我如何解决的,通过定义自定义图像视图并在OnDraw方法中进行一些更改,我还添加了代码以降低图像的亮度,因此当您调整大小时,真实背后的背景图像看起来不错矩形:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;
public class CustomCropImageView extends ImageView implements View.OnTouchListener{
// Bitmap to draw.
Bitmap myBitmap;
// Fundamental attributes.
int xPos, yPos;
int originWidth, originHeight;
int widthImg, heightImg;
int xCrop, yCrop;
int cropWidth, cropHeight;
int offsetLeft = 0, offsetRight = 0, offsetTop = 0, offsetBottom = 0;
// List of anchor point rectangle.
List<Rect> anchorPoints;
int anchorPointW = 30;
int halfAnchorPointW = anchorPointW / 2;
// Background bitmap for cropping.
Bitmap darkBitmap;
public CustomCropImageView(Context context){
super(context);
xPos = yPos = xCrop = yCrop = 0;
// setOnTouchListener(this);
}
public CustomCropImageView(Context context, AttributeSet attSet){
super(context, attSet);
xPos = yPos = xCrop = yCrop = 0;
// setOnTouchListener(this);
}
Integer[] myDWAndH;
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if(drawable == null)
return;
if(originWidth == 0 && originHeight == 0){
Bitmap tmp = ((BitmapDrawable)drawable).getBitmap();
myBitmap = tmp.copy(Bitmap.Config.ARGB_8888, true);
originWidth = myBitmap.getWidth();
originHeight = myBitmap.getHeight();
myDWAndH = getScreenWidthAndHeight();
widthImg = cropWidth = myDWAndH[0] - anchorPointW;
heightImg = cropHeight = (int)((float)myDWAndH[0]*((float)originHeight / (float)originWidth)) - anchorPointW;
yPos = yCrop = (myDWAndH[1] - heightImg) / 2;
myBitmap = Bitmap.createScaledBitmap(myBitmap, widthImg, heightImg, false);
createDarkBitmap(myBitmap);
initAnchorPoint();
}
Paint myPaint = new Paint();
canvas.drawBitmap(darkBitmap, xPos + halfAnchorPointW, yPos + halfAnchorPointW, myPaint);
drawAnchorRectangle(canvas);
}
void drawAnchorRectangle(Canvas canvas){
// Anchor rectangle.
Paint myPaint = new Paint();
canvas.drawBitmap(myBitmap, new Rect(offsetLeft, offsetTop, cropWidth + offsetRight, cropHeight + offsetBottom),
new Rect(xCrop + halfAnchorPointW + offsetLeft, yCrop + halfAnchorPointW + offsetTop,
xCrop + halfAnchorPointW + cropWidth + offsetRight, yCrop + halfAnchorPointW + cropHeight + offsetBottom), myPaint);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setColor(getContext().getResources().getColor(R.color.ImgVBorder));
myPaint.setStrokeWidth(5);
Rect myRect = new Rect(xCrop + halfAnchorPointW + offsetLeft, yCrop + halfAnchorPointW + offsetTop,
xCrop + halfAnchorPointW + cropWidth + offsetRight, yCrop + halfAnchorPointW + cropHeight + offsetBottom);
canvas.drawRect(myRect, myPaint);
// Anchor point.
myPaint.setStyle(Paint.Style.FILL);
myPaint.setColor(getContext().getResources().getColor(R.color.ImgVAnchorPoint));
// Top left.
canvas.drawRect(anchorPoints.get(0), myPaint);
// Top right.
canvas.drawRect(anchorPoints.get(1), myPaint);
// Bottom left.
canvas.drawRect(anchorPoints.get(2), myPaint);
// Bottom right.
canvas.drawRect(anchorPoints.get(3), myPaint);
}
void initAnchorPoint(){
if(anchorPoints != null)
anchorPoints.clear();
else
anchorPoints = new ArrayList<>();
// Top left.
anchorPoints.add(new Rect(xCrop + offsetLeft, yCrop + offsetTop,
xCrop + anchorPointW + offsetLeft, yCrop + anchorPointW + offsetTop));
// Top right.
anchorPoints.add(new Rect(xCrop + cropWidth + offsetRight, yCrop + offsetTop,
xCrop + cropWidth + anchorPointW + offsetRight, yCrop + anchorPointW + offsetTop));
// Bottom left.
anchorPoints.add(new Rect(xCrop + offsetLeft, yCrop + cropHeight + offsetBottom,
xCrop + anchorPointW + offsetLeft, yCrop + cropHeight + anchorPointW + offsetBottom));
// Bottom right.
anchorPoints.add(new Rect(xCrop + cropWidth + offsetRight, yCrop + cropHeight + offsetBottom,
xCrop + cropWidth + anchorPointW + offsetRight, yCrop + cropHeight + anchorPointW + offsetBottom));
}
Integer[] getScreenWidthAndHeight(){
DisplayMetrics dMetrics = new DisplayMetrics();
((MainActivity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(dMetrics);
Integer[] myResult = new Integer[2];
myResult[0] = dMetrics.widthPixels - 40;
myResult[1] = dMetrics.heightPixels;
return myResult;
}
int anchorChoice = -1;
void setAnchorAction(MotionEvent event){
int x = (int)event.getRawX();
int y = (int)event.getRawY();
int offset = 50 + anchorPointW;
anchorChoice = -1;
if(y > (anchorPoints.get(0).top - offset) && y < (anchorPoints.get(0).bottom + offset)){
if(x < (anchorPoints.get(0).right + offset) && x > (anchorPoints.get(0).left - offset)){
anchorChoice = 0;
}
else if(x < (anchorPoints.get(1).right + offset) && x > (anchorPoints.get(1).left - offset))
anchorChoice = 1;
}
else if(y > (anchorPoints.get(2).top - offset) && y < (anchorPoints.get(2).bottom + offset)){
if(x < (anchorPoints.get(2).right + offset) && x > (anchorPoints.get(2).left - offset)){
anchorChoice = 2;
}
else if(x < (anchorPoints.get(3).right + offset) && x > (anchorPoints.get(3).left - offset))
anchorChoice = 3;
}
}
void resizeRectangle(MotionEvent event){
if(anchorChoice == -1)
return;
int x = (int)event.getRawX();
int y = (int)event.getRawY();
int dif = 0;
initAnchorPoint();
invalidate();
// xCrop + halfAnchorPointW + offsetLeft, yCrop + halfAnchorPointW + offsetTop,
// xCrop + halfAnchorPointW + cropWidth + offsetRight, yCrop + halfAnchorPointW + cropHeight + offsetBottom
int prevOLeft = offsetLeft;
int prevORight = offsetRight;
int prevOTop = offsetTop;
int prevOBottom = offsetBottom;
if(anchorChoice == 0){
offsetLeft = (x - xCrop - halfAnchorPointW);
offsetTop = (y - yCrop - halfAnchorPointW);
}
else if(anchorChoice == 1){
offsetRight = (x - xCrop - halfAnchorPointW - cropWidth);
offsetTop = (y - yCrop - halfAnchorPointW);
}
else if(anchorChoice == 2){
offsetLeft = (x - xCrop - halfAnchorPointW);
offsetBottom = (y - yCrop - halfAnchorPointW - cropHeight);
}
else if(anchorChoice == 3){
offsetRight = (x - xCrop - halfAnchorPointW - cropWidth);
offsetBottom = (y - yCrop - halfAnchorPointW - cropHeight);
}
// Boundaries.
// Left boundary.
if(xCrop + offsetLeft < xCrop)
offsetLeft = 0;
if(xCrop + halfAnchorPointW + cropWidth + offsetRight < xCrop + anchorPointW + offsetLeft)
offsetRight = prevORight;
// Top boundary.
if(yCrop + offsetTop < yCrop)
offsetTop = 0;
if(yCrop + halfAnchorPointW + cropHeight + offsetBottom < yCrop + anchorPointW + offsetTop)
offsetBottom = prevOBottom;
// Right boundary.
if(xCrop + halfAnchorPointW + cropWidth + offsetRight > xCrop + halfAnchorPointW + cropWidth)
offsetRight = 0;
if(xCrop + anchorPointW + offsetLeft > xCrop + halfAnchorPointW + cropWidth + offsetRight)
offsetLeft = prevOLeft;
// Bottom boundary.
if(yCrop + halfAnchorPointW + cropHeight + offsetBottom > yCrop + halfAnchorPointW + cropHeight)
offsetBottom = 0;
if(yCrop + anchorPointW + offsetTop > yCrop + halfAnchorPointW + cropHeight + offsetBottom)
offsetTop = prevOTop;
// End boundaries.
return;
}
void createDarkBitmap(Bitmap processedBitmap){
darkBitmap = Bitmap.createBitmap(processedBitmap.getWidth(), processedBitmap.getHeight(), Bitmap.Config.ARGB_8888);
int substractValue = 220;
for(int i = 0; i < processedBitmap.getWidth(); i++){
for(int j = 0; j < processedBitmap.getHeight(); j++){
int pixelToProcess = processedBitmap.getPixel(i, j);
// Get component infos.
int r = Color.red(pixelToProcess);
int g = Color.green(pixelToProcess);
int b = Color.blue(pixelToProcess);
int alpha = Color.alpha(pixelToProcess);
// Process component info.
alpha -= substractValue;
// alpha = alpha - substractValue;
darkBitmap.setPixel(i, j, Color.argb(alpha, r, g, b));
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
final String TAG = "!!!123";
switch (action) {
case MotionEvent.ACTION_DOWN:
setAnchorAction(event);
Log.d(TAG, "" + anchorChoice);
return true;
case MotionEvent.ACTION_MOVE:
resizeRectangle(event);
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "Action was UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.d(TAG, "Action was CANCEL");
break;
case MotionEvent.ACTION_OUTSIDE:
Log.d(TAG, "Movement occurred outside bounds of current screen element");
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return super.onTouchEvent(event);
}
}