添加主窗口封面刷新机制和剪裁图片调试日志
- 添加剪裁图片保存时的调试日志输出 - 添加广播机制通知主窗口刷新封面图片 - 优化剪裁画布的显示和缩放功能 - 添加缩放按钮和ZoomContainerView支持 - 添加新的图标资源(ic_done、ic_zoom_in、ic_zoom_out)
This commit is contained in:
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
@@ -38,12 +39,18 @@ public class CropCanvasView extends View {
|
||||
private RectF imageBounds = new RectF();
|
||||
private RectF canvasBounds = new RectF();
|
||||
private Bitmap originalBitmap;
|
||||
private Bitmap canvasBitmap;
|
||||
private Bitmap displayBitmap;
|
||||
private RectF initialSpanRect;
|
||||
private float initialSpan;
|
||||
private int backgroundColor = Color.GREEN;
|
||||
private boolean colorPickMode = false;
|
||||
private float pickX, pickY;
|
||||
|
||||
private float displayScale = 1.0f;
|
||||
private float displayOffsetX = 0f;
|
||||
private float displayOffsetY = 0f;
|
||||
private static final int MAX_DISPLAY_SIZE = 2048;
|
||||
|
||||
public CropCanvasView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
@@ -74,7 +81,43 @@ public class CropCanvasView extends View {
|
||||
}
|
||||
|
||||
public void setImageBitmap(Bitmap bitmap) {
|
||||
if (displayBitmap != null && displayBitmap != originalBitmap) {
|
||||
displayBitmap.recycle();
|
||||
}
|
||||
this.originalBitmap = bitmap;
|
||||
createDisplayBitmap();
|
||||
}
|
||||
|
||||
private void createDisplayBitmap() {
|
||||
if (displayBitmap != null && displayBitmap != originalBitmap) {
|
||||
displayBitmap.recycle();
|
||||
displayBitmap = null;
|
||||
}
|
||||
if (originalBitmap == null || originalBitmap.isRecycled()) {
|
||||
return;
|
||||
}
|
||||
int w = originalBitmap.getWidth();
|
||||
int h = originalBitmap.getHeight();
|
||||
float scale = 1.0f;
|
||||
if (w > MAX_DISPLAY_SIZE || h > MAX_DISPLAY_SIZE) {
|
||||
scale = Math.min((float) MAX_DISPLAY_SIZE / w, (float) MAX_DISPLAY_SIZE / h);
|
||||
int newW = (int) (w * scale);
|
||||
int newH = (int) (h * scale);
|
||||
displayBitmap = Bitmap.createScaledBitmap(originalBitmap, newW, newH, true);
|
||||
} else {
|
||||
displayBitmap = originalBitmap;
|
||||
}
|
||||
displayBitmapScale = scale;
|
||||
}
|
||||
|
||||
private float displayBitmapScale = 1.0f;
|
||||
|
||||
public Bitmap getOriginalBitmap() {
|
||||
return originalBitmap;
|
||||
}
|
||||
|
||||
public float getDisplayBitmapScale() {
|
||||
return displayBitmapScale;
|
||||
}
|
||||
|
||||
public void initCanvas(int imgWidth, int imgHeight, float ratio) {
|
||||
@@ -102,31 +145,61 @@ 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 void getDisplayMatrix(Matrix matrix) {
|
||||
if (canvasWidth <= 0 || canvasHeight <= 0 || getWidth() <= 0 || getHeight() <= 0) {
|
||||
return;
|
||||
}
|
||||
matrix.reset();
|
||||
|
||||
float displayScaleX = (float) getWidth() / canvasWidth;
|
||||
float displayScaleY = (float) getHeight() / canvasHeight;
|
||||
displayScale = Math.min(displayScaleX, displayScaleY);
|
||||
|
||||
displayOffsetX = (getWidth() - canvasWidth * displayScale) / 2f;
|
||||
displayOffsetY = (getHeight() - canvasHeight * displayScale) / 2f;
|
||||
|
||||
matrix.postTranslate(displayOffsetX, displayOffsetY);
|
||||
matrix.postScale(displayScale, displayScale);
|
||||
}
|
||||
|
||||
public Bitmap getCanvasBitmap() {
|
||||
return canvasBitmap;
|
||||
public float screenToImageX(float screenX) {
|
||||
return (screenX - displayOffsetX) / displayScale;
|
||||
}
|
||||
|
||||
public float screenToImageY(float screenY) {
|
||||
return (screenY - displayOffsetY) / displayScale;
|
||||
}
|
||||
|
||||
public float imageToScreenX(float imageX) {
|
||||
return imageX * displayScale + displayOffsetX;
|
||||
}
|
||||
|
||||
public float imageToScreenY(float imageY) {
|
||||
return imageY * displayScale + displayOffsetY;
|
||||
}
|
||||
|
||||
public int getImageColorAt(float screenX, float screenY) {
|
||||
Bitmap bmp = (displayBitmap != null) ? displayBitmap : originalBitmap;
|
||||
if (bmp == null || bmp.isRecycled()) {
|
||||
return Color.TRANSPARENT;
|
||||
}
|
||||
float imgX = screenToImageX(screenX);
|
||||
float imgY = screenToImageY(screenY);
|
||||
int bmpX = (int) ((imgX - imageBounds.left) * displayBitmapScale);
|
||||
int bmpY = (int) ((imgY - imageBounds.top) * displayBitmapScale);
|
||||
if (bmpX >= 0 && bmpX < bmp.getWidth() &&
|
||||
bmpY >= 0 && bmpY < bmp.getHeight()) {
|
||||
return bmp.getPixel(bmpX, bmpY);
|
||||
}
|
||||
return Color.TRANSPARENT;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(int color) {
|
||||
this.backgroundColor = color;
|
||||
createCanvasBitmap();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -148,30 +221,8 @@ public class CropCanvasView extends View {
|
||||
}
|
||||
|
||||
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);
|
||||
int oldCanvasW = canvasWidth;
|
||||
int oldCanvasH = canvasHeight;
|
||||
canvasWidth = (int) (canvasWidth * scale);
|
||||
canvasHeight = (int) (canvasHeight * scale);
|
||||
|
||||
float left = (canvasWidth - imageWidth) / 2f;
|
||||
float top = (canvasHeight - imageHeight) / 2f;
|
||||
imageBounds.set(left, top, left + imageWidth, top + imageHeight);
|
||||
canvasBounds.set(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
if (cropRect != null) {
|
||||
float scaleX = (float) canvasWidth / oldCanvasW;
|
||||
float scaleY = (float) canvasHeight / oldCanvasH;
|
||||
cropRect.left *= scaleX;
|
||||
cropRect.top *= scaleY;
|
||||
cropRect.right *= scaleX;
|
||||
cropRect.bottom *= scaleY;
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public RectF getCropRect() {
|
||||
@@ -194,6 +245,14 @@ public class CropCanvasView extends View {
|
||||
return new RectF(imageBounds);
|
||||
}
|
||||
|
||||
public float getBitmapScale() {
|
||||
return displayScale;
|
||||
}
|
||||
|
||||
public float getDisplayScale() {
|
||||
return displayScale;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int w = canvasWidth > 0 ? canvasWidth : 0;
|
||||
@@ -201,15 +260,51 @@ public class CropCanvasView extends View {
|
||||
setMeasuredDimension(w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
getDisplayMatrix(new Matrix());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
if (canvasBitmap != null && !canvasBitmap.isRecycled()) {
|
||||
canvas.drawBitmap(canvasBitmap, 0, 0, null);
|
||||
}
|
||||
if (cropRect == null) return;
|
||||
|
||||
if (cropRect != null) {
|
||||
if (displayBitmap != null && !displayBitmap.isRecycled()) {
|
||||
canvas.save();
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
getDisplayMatrix(matrix);
|
||||
canvas.concat(matrix);
|
||||
|
||||
canvas.drawColor(backgroundColor);
|
||||
|
||||
if (displayBitmap == originalBitmap) {
|
||||
canvas.drawBitmap(displayBitmap, imageBounds.left, imageBounds.top, imagePaint);
|
||||
} else {
|
||||
float invScale = 1f / displayBitmapScale;
|
||||
canvas.save();
|
||||
canvas.scale(invScale, invScale);
|
||||
canvas.drawBitmap(displayBitmap, imageBounds.left * displayBitmapScale,
|
||||
imageBounds.top * displayBitmapScale, imagePaint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
|
||||
canvas.drawRect(cropRect, borderPaint);
|
||||
|
||||
float scX = imageToScreenX(cropRect.left);
|
||||
float scY = imageToScreenY(cropRect.top);
|
||||
float scR = imageToScreenX(cropRect.right);
|
||||
float scB = imageToScreenY(cropRect.bottom);
|
||||
canvas.drawCircle(scX, scY, 12, cornerPaint);
|
||||
canvas.drawCircle(scR, scY, 12, cornerPaint);
|
||||
canvas.drawCircle(scX, scB, 12, cornerPaint);
|
||||
canvas.drawCircle(scR, scB, 12, cornerPaint);
|
||||
} else {
|
||||
canvas.drawRect(cropRect, borderPaint);
|
||||
|
||||
canvas.drawCircle(cropRect.left, cropRect.top, 12, cornerPaint);
|
||||
@@ -387,14 +482,6 @@ public class CropCanvasView extends View {
|
||||
}
|
||||
|
||||
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;
|
||||
return getImageColorAt(x, y);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user