Compare commits

..

6 Commits

Author SHA1 Message Date
6d521fefdb <gallery>APK 15.0.13 release Publish. 2026-05-01 09:21:07 +08:00
f7932c134f 编译调试 2026-05-01 09:18:40 +08:00
93c59b0424 feat: 封面剪裁窗口使用与图片浏览窗口一致的背景颜色设置
- CropCanvasView: 将画布背景从固定的 Color.BLUE 改为支持 3 种背景类型
  (灰白棋盘格 / 全白 / 全黑),与 ImageViewerActivity 保持一致
  - 新增 bgType 字段、setBackgroundType() / getBackgroundType() 方法
  - 新增 drawBackground() 统一绘制方法,用于 onDraw() 和 getCanvasBitmap()
  - 棋盘格使用 Drawable.draw() 渲染 Vector 到 Bitmap,再通过 BitmapShader 平铺

- CropActivity: 从 Preferences 读取保存的 bgType 并应用到画布
  - 将颜色拾取按钮替换为背景选择按钮 (ic_bg),弹出单选对话框切换背景
  - 切换时调用 prefs.setBgType() 保存,与图片浏览窗口共享同一数据源
  - 工具栏颜色指示器随背景类型更新
  - 剪裁信息对话框改为显示背景类型名称
2026-05-01 09:15:30 +08:00
fe248349df <gallery>APK 15.0.12 release Publish. 2026-05-01 08:34:01 +08:00
4790238343 更新图片浏览窗口工具栏Gallery按钮图标
- 将ImageViewerActivity工具栏中的btn_gallery图标从ic_cover替换为ic_view_gallery_outline
- 修改ic_view_gallery_outline的fillColor从黑色(#ff000000)改为白色(#FFFFFF),与工具栏其他图标颜色保持一致
2026-05-01 08:31:11 +08:00
f144d91bb6 添加ic_view_gallery_outline图标 2026-05-01 08:22:37 +08:00
5 changed files with 132 additions and 40 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Fri May 01 04:09:20 HKT 2026
stageCount=12
#Fri May 01 09:21:07 HKT 2026
stageCount=14
libraryProject=
baseVersion=15.0
publishVersion=15.0.11
publishVersion=15.0.13
buildCount=0
baseBetaVersion=15.0.12
baseBetaVersion=15.0.14

View File

@@ -43,6 +43,7 @@ public class CropActivity extends AppCompatActivity {
private int cropWidth = 240;
private int cropHeight = 120;
private float cropRatio = 2.0f;
private Preferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -54,7 +55,8 @@ public class CropActivity extends AppCompatActivity {
cropWidth = getIntent().getIntExtra(EXTRA_CROP_WIDTH, 240);
cropHeight = getIntent().getIntExtra(EXTRA_CROP_HEIGHT, 120);
Preferences prefs = new Preferences(this);
prefs = new Preferences(this);
int bgType = prefs.getBgType();
if (cropWidth > 0 && cropHeight > 0) {
cropRatio = (float) cropWidth / cropHeight;
} else {
@@ -70,13 +72,12 @@ public class CropActivity extends AppCompatActivity {
}
});
final ImageView btnColorPick = findViewById(R.id.btn_color_pick);
btnColorPick.setOnClickListener(new View.OnClickListener() {
final ImageView btnBg = findViewById(R.id.btn_color_pick);
btnBg.setImageResource(R.drawable.ic_bg);
btnBg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean pickMode = !cropCanvasView.isColorPickMode();
cropCanvasView.setColorPickMode(pickMode);
btnColorPick.setAlpha(pickMode ? 0.5f : 1.0f);
showBgDialog();
}
});
@@ -117,39 +118,56 @@ public class CropActivity extends AppCompatActivity {
final View colorView = findViewById(R.id.color_view);
final GradientDrawable colorDrawable = (GradientDrawable) colorView.getBackground();
cropCanvasView.setBackgroundType(bgType);
updateColorView(colorDrawable, bgType);
cropCanvasView.setOnBackgroundColorChangedListener(new CropCanvasView.OnBackgroundColorChangedListener() {
@Override
public void onBackgroundColorChanged(int color) {
colorDrawable.setColor(color);
}
});
cropCanvasView.setOnColorPickedListener(new CropCanvasView.OnColorPickedListener() {
@Override
public void onColorPicked(int color) {
int pickX = cropCanvasView.getLastPickImageX();
int pickY = cropCanvasView.getLastPickImageY();
colorDrawable.setColor(color);
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);
}
});
colorDrawable.setColor(cropCanvasView.getBackgroundColor());
loadImage();
}
private void updateColorView(GradientDrawable drawable, int bgType) {
switch (bgType) {
case 0:
drawable.setColor(0xFF808080);
break;
case 1:
drawable.setColor(0xFFFFFFFF);
break;
case 2:
default:
drawable.setColor(0xFF000000);
break;
}
}
private void showBgDialog() {
final String[] bgNames = {"灰白相间", "全白", "全黑"};
final int[] bgDrawables = {R.drawable.bg_checkerboard, R.drawable.bg_white, R.drawable.bg_black};
final View colorView = findViewById(R.id.color_view);
final GradientDrawable colorDrawable = (GradientDrawable) colorView.getBackground();
final int currentBgType = cropCanvasView.getBackgroundType();
new AlertDialog.Builder(this)
.setTitle("选择背景")
.setSingleChoiceItems(bgNames, currentBgType, new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
cropCanvasView.setBackgroundType(which);
prefs.setBgType(which);
updateColorView(colorDrawable, which);
dialog.dismiss();
}
})
.setNegativeButton("取消", null)
.show();
}
private void loadImage() {
try {
if (imagePath != null && new File(imagePath).exists()) {
@@ -261,7 +279,9 @@ public class CropActivity extends AppCompatActivity {
info.append("画布宽度: ").append(cropCanvasView.getCanvasWidth()).append("px\n");
info.append("画布高度: ").append(cropCanvasView.getCanvasHeight()).append("px\n");
info.append("\n=== 拾取颜色 ===\n");
info.append("\n=== 背景类型 ===\n");
String[] bgNames = {"灰白相间", "全白", "全黑"};
info.append("背景: ").append(bgNames[cropCanvasView.getBackgroundType()]).append("\n");
int bgColor = cropCanvasView.getBackgroundColor();
info.append("背景颜色: #").append(String.format("%06X", bgColor & 0xFFFFFF)).append("\n");
info.append("拾取坐标: ").append(cropCanvasView.getLastPickImageX()).append(",")

View File

@@ -2,11 +2,14 @@ package cc.winboll.studio.gallery;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -71,6 +74,10 @@ public class CropCanvasView extends View {
private Bitmap displayBitmap;
private RectF initialSpanRect;
private float initialSpan;
private int bgType = 2;
private Bitmap tileBitmap;
private BitmapShader tileShader;
private Paint bgPaint;
private int backgroundColor = Color.BLUE;
private boolean colorPickMode = false;
private int previewColor = 0;
@@ -111,6 +118,60 @@ public class CropCanvasView extends View {
cornerPaint = new Paint();
cornerPaint.setColor(Color.WHITE);
cornerPaint.setStyle(Paint.Style.FILL);
bgType = 2;
bgPaint = new Paint();
initTileBitmap();
}
private void initTileBitmap() {
if (tileBitmap != null && !tileBitmap.isRecycled()) {
tileBitmap.recycle();
tileBitmap = null;
}
tileShader = null;
if (bgType == 0) {
Drawable drawable = getContext().getDrawable(R.drawable.bg_checkerboard);
if (drawable != null) {
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
if (w <= 0) w = 10;
if (h <= 0) h = 10;
tileBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(tileBitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(c);
tileShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
}
}
}
public void setBackgroundType(int type) {
if (bgType != type) {
bgType = type;
initTileBitmap();
invalidate();
}
}
public int getBackgroundType() {
return bgType;
}
private void drawBackground(Canvas canvas) {
if (bgType == 0 && tileShader != null) {
bgPaint.setShader(tileShader);
canvas.drawRect(canvasBounds, bgPaint);
} else if (bgType == 1) {
bgPaint.setShader(null);
bgPaint.setColor(Color.WHITE);
canvas.drawRect(canvasBounds, bgPaint);
} else {
bgPaint.setShader(null);
bgPaint.setColor(Color.BLACK);
canvas.drawRect(canvasBounds, bgPaint);
}
}
public void setImageBitmap(Bitmap bitmap) {
@@ -175,7 +236,7 @@ public class CropCanvasView extends View {
}
Bitmap canvasBmp = Bitmap.createBitmap(canvasWidth, canvasHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(canvasBmp);
canvas.drawColor(backgroundColor);
drawBackground(canvas);
if (displayBitmap != null && !displayBitmap.isRecycled()) {
if (displayBitmap == originalBitmap) {
canvas.drawBitmap(displayBitmap, imageBounds.left, imageBounds.top, imagePaint);
@@ -409,7 +470,7 @@ public class CropCanvasView extends View {
getDisplayMatrix(matrix);
canvas.concat(matrix);
canvas.drawColor(backgroundColor);
drawBackground(canvas);
if (displayBitmap == originalBitmap) {
canvas.drawBitmap(displayBitmap, imageBounds.left, imageBounds.top, imagePaint);
@@ -523,7 +584,7 @@ public class CropCanvasView extends View {
if (imageBounds.contains(imgX, imgY)) {
previewColor = getImageColorAt(x, y);
} else if (canvasBounds.contains(x, y)) {
previewColor = backgroundColor;
previewColor = (bgType == 1) ? Color.WHITE : Color.BLACK;
} else {
previewColor = Color.TRANSPARENT;
}
@@ -545,7 +606,7 @@ public class CropCanvasView extends View {
pickedColor = colorAtPoint;
backgroundColor = colorAtPoint;
} else {
pickedColor = backgroundColor;
pickedColor = (bgType == 1) ? Color.WHITE : Color.BLACK;
}
if (colorPickedListener != null) {
colorPickedListener.onColorPicked(pickedColor);

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M1,3V21H23V3H1M21,5V14H3V5H21M11,16V19H8V16H11M3,16H6V19H3V16M13,19V16H16V19H13M18,19V16H21V19H18Z"/>
</vector>

View File

@@ -41,7 +41,7 @@
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_cover"
android:src="@drawable/ic_view_gallery_outline"
android:contentDescription="Gallery"/>
<ImageButton