diff --git a/gallery/build.properties b/gallery/build.properties
index 3508e42..401922c 100644
--- a/gallery/build.properties
+++ b/gallery/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue Apr 28 10:57:44 HKT 2026
+#Tue Apr 28 13:52:30 CST 2026
stageCount=8
libraryProject=
baseVersion=15.0
publishVersion=15.0.7
-buildCount=0
+buildCount=26
baseBetaVersion=15.0.8
diff --git a/gallery/src/main/java/cc/winboll/studio/gallery/CropActivity.java b/gallery/src/main/java/cc/winboll/studio/gallery/CropActivity.java
index 68e9b03..8f3f14d 100644
--- a/gallery/src/main/java/cc/winboll/studio/gallery/CropActivity.java
+++ b/gallery/src/main/java/cc/winboll/studio/gallery/CropActivity.java
@@ -5,13 +5,21 @@ import android.graphics.BitmapFactory;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.RectF;
+import android.net.Uri;
+import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.SeekBar;
+import android.widget.TextView;
import android.widget.Toast;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import cc.winboll.studio.libappbase.LogUtils;
import java.io.File;
@@ -78,6 +86,13 @@ public class CropActivity extends AppCompatActivity {
}
});
+ findViewById(R.id.btn_info).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showCropInfoDialog();
+ }
+ });
+
zoomContainer = findViewById(R.id.zoom_container);
SeekBar seekBarZoom = findViewById(R.id.seekbar_zoom);
@@ -110,6 +125,18 @@ public class CropActivity extends AppCompatActivity {
cropCanvasView.setOnColorPickedListener(new CropCanvasView.OnColorPickedListener() {
@Override
public void onColorPicked(int color) {
+ int pickX = cropCanvasView.getLastPickImageX();
+ int pickY = cropCanvasView.getLastPickImageY();
+ Toast.makeText(CropActivity.this,
+ "颜色已拾取: #" + String.format("%06X", color & 0xFFFFFF) +
+ " (" + pickX + "," + pickY + ")",
+ Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ cropCanvasView.setOnColorPickEndListener(new CropCanvasView.OnColorPickEndListener() {
+ @Override
+ public void onColorPickEnd() {
cropCanvasView.setColorPickMode(false);
btnColorPick.setAlpha(1.0f);
}
@@ -225,6 +252,67 @@ public class CropActivity extends AppCompatActivity {
}
}
+ private void showCropInfoDialog() {
+ StringBuilder info = new StringBuilder();
+ info.append("=== 画布信息 ===\n");
+ info.append("画布宽度: ").append(cropCanvasView.getCanvasWidth()).append("px\n");
+ info.append("画布高度: ").append(cropCanvasView.getCanvasHeight()).append("px\n");
+
+ info.append("\n=== 拾取颜色 ===\n");
+ int bgColor = cropCanvasView.getBackgroundColor();
+ info.append("背景颜色: #").append(String.format("%06X", bgColor & 0xFFFFFF)).append("\n");
+ info.append("拾取坐标: ").append(cropCanvasView.getLastPickImageX()).append(",")
+ .append(cropCanvasView.getLastPickImageY()).append("\n");
+
+ info.append("\n=== 裁剪结果 ===\n");
+ RectF cropRect = cropCanvasView.getCropRect();
+ if (cropRect != null) {
+ info.append("裁剪区域: ").append((int)cropRect.left).append(",")
+ .append((int)cropRect.top).append(",")
+ .append((int)cropRect.right).append(",")
+ .append((int)cropRect.bottom).append("\n");
+ info.append("裁剪宽度: ").append((int)cropRect.width()).append("px\n");
+ info.append("裁剪高度: ").append((int)cropRect.height()).append("px\n");
+ }
+
+ Bitmap canvasBitmap = cropCanvasView.getCanvasBitmap();
+ final Bitmap[] previewHolder = new Bitmap[1];
+ if (canvasBitmap != null && !canvasBitmap.isRecycled() && cropRect != null) {
+ int bmpX = Math.max(0, (int) cropRect.left);
+ int bmpY = Math.max(0, (int) cropRect.top);
+ int bmpW = Math.min((int) cropRect.width(), canvasBitmap.getWidth() - bmpX);
+ int bmpH = Math.min((int) cropRect.height(), canvasBitmap.getHeight() - bmpY);
+ if (bmpW > 0 && bmpH > 0) {
+ previewHolder[0] = Bitmap.createBitmap(canvasBitmap, bmpX, bmpY, bmpW, bmpH);
+ }
+ }
+
+ final Bitmap previewBitmap = previewHolder[0];
+
+ View dialogView = getLayoutInflater().inflate(R.layout.dialog_crop_info, null);
+ TextView infoText = dialogView.findViewById(R.id.info_text);
+ ImageView previewImage = dialogView.findViewById(R.id.preview_image);
+ infoText.setText(info.toString());
+ if (previewBitmap != null) {
+ previewImage.setImageBitmap(previewBitmap);
+ }
+
+ AlertDialog dialog = new AlertDialog.Builder(this)
+ .setTitle("裁剪信息")
+ .setView(dialogView)
+ .setPositiveButton("确定", null)
+ .create();
+ dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (previewBitmap != null && !previewBitmap.isRecycled()) {
+ previewBitmap.recycle();
+ }
+ }
+ });
+ dialog.show();
+ }
+
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/gallery/src/main/java/cc/winboll/studio/gallery/CropCanvasView.java b/gallery/src/main/java/cc/winboll/studio/gallery/CropCanvasView.java
index 9053108..ff35972 100644
--- a/gallery/src/main/java/cc/winboll/studio/gallery/CropCanvasView.java
+++ b/gallery/src/main/java/cc/winboll/studio/gallery/CropCanvasView.java
@@ -20,8 +20,13 @@ public class CropCanvasView extends View {
void onColorPicked(int color);
}
+ public interface OnColorPickEndListener {
+ void onColorPickEnd();
+ }
+
private OnBackgroundColorChangedListener backgroundColorChangedListener;
private OnColorPickedListener colorPickedListener;
+ private OnColorPickEndListener colorPickEndListener;
public void setOnBackgroundColorChangedListener(OnBackgroundColorChangedListener listener) {
this.backgroundColorChangedListener = listener;
@@ -30,6 +35,10 @@ public class CropCanvasView extends View {
public void setOnColorPickedListener(OnColorPickedListener listener) {
this.colorPickedListener = listener;
}
+
+ public void setOnColorPickEndListener(OnColorPickEndListener listener) {
+ this.colorPickEndListener = listener;
+ }
private Paint imagePaint;
private Paint borderPaint;
private Paint cornerPaint;
@@ -65,6 +74,8 @@ public class CropCanvasView extends View {
private int backgroundColor = Color.BLUE;
private boolean colorPickMode = false;
private int previewColor = 0;
+ private float lastPickX = 0;
+ private float lastPickY = 0;
private float pickX, pickY;
private float displayScale = 1.0f;
@@ -270,6 +281,40 @@ public class CropCanvasView extends View {
return backgroundColor;
}
+ public int getPreviewColor() {
+ return previewColor;
+ }
+
+ public float getLastPickX() {
+ return lastPickX;
+ }
+
+ public float getLastPickY() {
+ return lastPickY;
+ }
+
+ public int getLastPickImageX() {
+ if (originalBitmap == null || originalBitmap.isRecycled()) {
+ return 0;
+ }
+ float imgX = screenToImageX(lastPickX);
+ float imgY = screenToImageY(lastPickY);
+ int bmpX = (int) ((imgX - imageBounds.left) * displayBitmapScale);
+ int bmpY = (int) ((imgY - imageBounds.top) * displayBitmapScale);
+ return Math.max(0, Math.min(bmpX, originalBitmap.getWidth() - 1));
+ }
+
+ public int getLastPickImageY() {
+ if (originalBitmap == null || originalBitmap.isRecycled()) {
+ return 0;
+ }
+ float imgX = screenToImageX(lastPickX);
+ float imgY = screenToImageY(lastPickY);
+ int bmpX = (int) ((imgX - imageBounds.left) * displayBitmapScale);
+ int bmpY = (int) ((imgY - imageBounds.top) * displayBitmapScale);
+ return Math.max(0, Math.min(bmpY, originalBitmap.getHeight() - 1));
+ }
+
public void setColorPickMode(boolean enable) {
this.colorPickMode = enable;
if (enable) {
@@ -471,30 +516,11 @@ public class CropCanvasView extends View {
}
if (colorPickMode) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
if (originalBitmap != null && !originalBitmap.isRecycled()) {
- float imgX = screenToImageX(x);
- float imgY = screenToImageY(y);
- int bmpX = (int) ((imgX - imageBounds.left) * displayBitmapScale);
- int bmpY = (int) ((imgY - imageBounds.top) * displayBitmapScale);
- bmpX = Math.max(0, Math.min(bmpX, originalBitmap.getWidth() - 1));
- bmpY = Math.max(0, Math.min(bmpY, originalBitmap.getHeight() - 1));
- previewColor = originalBitmap.getPixel(bmpX, bmpY);
- if (backgroundColorChangedListener != null) {
- backgroundColorChangedListener.onBackgroundColorChanged(previewColor);
- }
- }
- return true;
- }
- if (event.getAction() == MotionEvent.ACTION_MOVE) {
- if (originalBitmap != null && !originalBitmap.isRecycled()) {
- float imgX = screenToImageX(x);
- float imgY = screenToImageY(y);
- int bmpX = (int) ((imgX - imageBounds.left) * displayBitmapScale);
- int bmpY = (int) ((imgY - imageBounds.top) * displayBitmapScale);
- bmpX = Math.max(0, Math.min(bmpX, originalBitmap.getWidth() - 1));
- bmpY = Math.max(0, Math.min(bmpY, originalBitmap.getHeight() - 1));
- previewColor = originalBitmap.getPixel(bmpX, bmpY);
+ previewColor = getImageColorAt(x, y);
+ lastPickX = x;
+ lastPickY = y;
if (backgroundColorChangedListener != null) {
backgroundColorChangedListener.onBackgroundColorChanged(previewColor);
}
@@ -502,14 +528,17 @@ public class CropCanvasView extends View {
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
- if (previewColor != 0) {
+ if (previewColor != 0 && previewColor != Color.TRANSPARENT) {
backgroundColor = previewColor;
if (colorPickedListener != null) {
colorPickedListener.onColorPicked(backgroundColor);
}
- previewColor = 0;
- invalidate();
}
+ if (colorPickEndListener != null) {
+ colorPickEndListener.onColorPickEnd();
+ }
+ previewColor = 0;
+ invalidate();
return true;
}
return true;
diff --git a/gallery/src/main/res/drawable/bg_dialog.xml b/gallery/src/main/res/drawable/bg_dialog.xml
new file mode 100644
index 0000000..5477c09
--- /dev/null
+++ b/gallery/src/main/res/drawable/bg_dialog.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/gallery/src/main/res/layout/activity_crop.xml b/gallery/src/main/res/layout/activity_crop.xml
index ca85d7c..6679297 100644
--- a/gallery/src/main/res/layout/activity_crop.xml
+++ b/gallery/src/main/res/layout/activity_crop.xml
@@ -55,6 +55,14 @@
android:layout_height="0dp"
android:layout_weight="1"/>
+
+
+
+
+
+
+
+
+
\ No newline at end of file