实现画布控件背景颜色拾取和剪裁画布功能

- 画布控件创建canvasBitmap保存背景和图片
- 剪裁时剪裁画布控件而非原图片
- 添加颜色拾取按钮和功能
- 可从图片中拾取颜色设置为背景
This commit is contained in:
2026-04-26 19:54:50 +08:00
parent 57c36b09ac
commit b01482470a
4 changed files with 121 additions and 43 deletions

View File

@@ -38,7 +38,11 @@ public class CropCanvasView extends View {
private RectF imageBounds = new RectF();
private RectF canvasBounds = new RectF();
private Bitmap originalBitmap;
private Bitmap canvasBitmap;
private float initialSpan;
private int backgroundColor = Color.GREEN;
private boolean colorPickMode = false;
private float pickX, pickY;
public CropCanvasView(Context context) {
super(context);
@@ -98,10 +102,51 @@ public class CropCanvasView extends View {
cropRect = new RectF(0, 0, canvasWidth, canvasHeight);
createCanvasBitmap();
requestLayout();
invalidate();
}
private void createCanvasBitmap() {
if (canvasBitmap != null) {
canvasBitmap.recycle();
}
canvasBitmap = Bitmap.createBitmap(canvasWidth, canvasHeight, Bitmap.Config.ARGB_8888);
android.graphics.Canvas canvas = new android.graphics.Canvas(canvasBitmap);
canvas.drawColor(backgroundColor);
if (originalBitmap != null && !originalBitmap.isRecycled()) {
canvas.drawBitmap(originalBitmap, imageBounds.left, imageBounds.top, imagePaint);
}
}
public Bitmap getCanvasBitmap() {
return canvasBitmap;
}
public void setBackgroundColor(int color) {
this.backgroundColor = color;
createCanvasBitmap();
invalidate();
}
public int getBackgroundColor() {
return backgroundColor;
}
public void setColorPickMode(boolean enable) {
this.colorPickMode = enable;
if (enable) {
pickX = -1;
pickY = -1;
}
invalidate();
}
public boolean isColorPickMode() {
return colorPickMode;
}
public void scaleToView(int viewWidth, int viewHeight) {
if (viewWidth > 0 && viewHeight > 0 && canvasWidth > 0 && canvasHeight > 0) {
float scale = Math.max((float) viewWidth / canvasWidth, (float) viewHeight / canvasHeight);
@@ -141,14 +186,6 @@ public class CropCanvasView extends View {
return canvasHeight;
}
public int getExtendWidth() {
return extendWidth;
}
public int getExtendHeight() {
return extendHeight;
}
public RectF getCanvasBounds() {
return new RectF(canvasBounds);
}
@@ -157,10 +194,6 @@ public class CropCanvasView extends View {
return new RectF(imageBounds);
}
public float getCoverRatio() {
return coverRatio;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = canvasWidth > 0 ? canvasWidth : 0;
@@ -172,10 +205,8 @@ public class CropCanvasView extends View {
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);
if (originalBitmap != null && !originalBitmap.isRecycled()) {
canvas.drawBitmap(originalBitmap, imageBounds.left, imageBounds.top, imagePaint);
if (canvasBitmap != null && !canvasBitmap.isRecycled()) {
canvas.drawBitmap(canvasBitmap, 0, 0, null);
}
if (cropRect != null) {
@@ -210,7 +241,7 @@ public class CropCanvasView extends View {
newHeight = newWidth / coverRatio;
cropRect.set(centerX - newWidth / 2, centerY - newHeight / 2,
centerX + newWidth / 2, centerY + newHeight / 2);
centerX + newWidth / 2, centerY + newHeight / 2);
initialSpan = span;
invalidate();
@@ -222,6 +253,17 @@ public class CropCanvasView extends View {
float x = event.getX();
float y = event.getY();
if (colorPickMode) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pickX = x;
pickY = y;
int color = getColorAt(x, y);
setBackgroundColor(color);
return true;
}
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
@@ -313,19 +355,24 @@ public class CropCanvasView extends View {
}
private int getActiveCorner(float x, float y) {
if (Math.abs(x - cropRect.left) <= touchArea && Math.abs(y - cropRect.top) <= touchArea) {
float dx = Math.abs(x - cropRect.left);
float dy = Math.abs(y - cropRect.top);
float dx2 = Math.abs(x - cropRect.right);
float dy2 = Math.abs(y - cropRect.bottom);
if (dx <= touchArea && dy <= touchArea) {
return CORNER_TOP_LEFT;
}
if (Math.abs(x - cropRect.right) <= touchArea && Math.abs(y - cropRect.top) <= touchArea) {
if (dx2 <= touchArea && dy <= touchArea) {
return CORNER_TOP_RIGHT;
}
if (Math.abs(x - cropRect.left) <= touchArea && Math.abs(y - cropRect.bottom) <= touchArea) {
if (dx <= touchArea && dy2 <= touchArea) {
return CORNER_BOTTOM_LEFT;
}
if (Math.abs(x - cropRect.right) <= touchArea && Math.abs(y - cropRect.bottom) <= touchArea) {
if (dx2 <= touchArea && dy2 <= touchArea) {
return CORNER_BOTTOM_RIGHT;
}
if (cropRect.contains(x, y)) {
if (x > cropRect.left && x < cropRect.right && y > cropRect.top && y < cropRect.bottom) {
return CORNER_CENTER;
}
return -1;
@@ -338,4 +385,16 @@ public class CropCanvasView extends View {
float y1 = event.getY(1);
return (float) Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
}
public int getColorAt(float x, float y) {
if (canvasBitmap != null && !canvasBitmap.isRecycled()) {
int bitmapX = (int) x;
int bitmapY = (int) y;
if (bitmapX >= 0 && bitmapX < canvasBitmap.getWidth() &&
bitmapY >= 0 && bitmapY < canvasBitmap.getHeight()) {
return canvasBitmap.getPixel(bitmapX, bitmapY);
}
}
return Color.TRANSPARENT;
}
}