Compare commits

...

51 Commits

Author SHA1 Message Date
Developer
62294598ca feat: 增加主题模式切换(跟随系统/浅色/暗色),修复暗色模式字体颜色不可读问题 2026-05-13 20:54:50 +08:00
Developer
acddb7d53e fix: 去除拼图maxCellDimension=800上限,直接使用原图尺寸×缩放因子 2026-05-12 23:40:41 +08:00
Developer
fc5c0e7a0a fix: 拍照后相册不显示图片(相册页面缺少初始加载) 2026-05-12 23:30:04 +08:00
Developer
1d7799f561 chore: 更新release apk 2026-05-12 23:10:08 +08:00
Developer
8d54f1c9dc feat: 拼图质量改为分辨率缩放,高清80%/标准50%/流畅30% 2026-05-12 23:05:35 +08:00
Developer
5ae2a05a3d docs: 更新 README 说明文档,补充 EXIF、文件名模板等功能说明 2026-04-23 20:33:29 +08:00
Developer
f7172869af feat: 设置界面增加文件名模板配置项 2026-04-23 18:33:11 +08:00
Developer
427e9166b3 fix: 修复CameraScreen编译错误,整合文件名模板功能 2026-04-23 18:16:45 +08:00
Developer
9455720516 feat: 相册按日期分组(今天/昨天/上月/更早) 2026-04-21 22:33:56 +08:00
Developer
697a6cae87 feat: 写入 EXIF GPS/时间/相机型号/作者,保存时带纬度经度 2026-04-20 21:32:59 +08:00
Developer
ccafe90442 修复闪光灯模式切换不生效问题 2026-04-19 19:55:48 +08:00
Developer
871f6637ac 相册预览界面增加删除按钮和二次确认 2026-04-18 12:14:06 +08:00
Developer
b85bc11c2a 高清质量改为100 2026-04-17 21:56:21 +08:00
Developer
958e232983 保留并上传 release APK 2026-03-27 23:31:50 +08:00
Developer
1095eb557d 添加拍照提示音和相册双指缩放功能 2026-03-27 23:08:00 +08:00
2687aabae5 修改媒体权限逻辑:创建checkshot文件夹,只读取该文件夹中的图片
- 修改GalleryScreen.kt中的loadImagesFromGallery函数,添加WHERE条件只读取checkshot文件夹中的图片
- 修改MergeScreen.kt中的getLatestImages函数,添加WHERE条件只读取checkshot文件夹中的图片
- 修改ImageProcessor.kt中的saveToGallery函数,将图片保存到checkshot文件夹(之前是InspectionCamera)
2026-03-20 22:13:40 +08:00
033e5c24cd 更新.gitignore和README.md 2026-03-18 23:12:35 +08:00
29ca63bbbd Update README to mark unimplemented features
- Mark '分类管理' as待开发 in图片管理 section
- Add checkmarks () for implemented features
- Add notes for待开发 features
2026-03-17 23:10:21 +08:00
f436275b7d Update README with '巡检相机'定位 and add interface screenshots
- Change project定位 to '巡检相机' (Inspection Camera)
- Add 4 interface screenshots: Camera, Gallery, Puzzle, Settings
- Keep all other documentation unchanged
2026-03-17 23:07:06 +08:00
8fb3af5518 Update README.md to follow standard format
- Rewrite README with clear sections: Features, Installation, Usage, Structure
- Add FAQ and contact information
- Keep project information concise and actionable
2026-03-15 23:32:46 +08:00
1d4cc5fede Configure .gitignore to properly ignore build artifacts
- Add comprehensive Android/Gradle ignore patterns
- Ignore compiled output, dependencies, and sensitive files
- Remove tracked build artifacts from repository
2026-03-15 23:31:07 +08:00
07cd627f60 Update README to reflect actual implementation
- Add release build instructions and signing configuration
- Complete AirTest testing setup instructions
- Document all settings options
- Correct file naming format description
2026-03-15 23:28:56 +08:00
4415f28d08 Add release build configuration with automatic signing
- Configure release build type with minify and shrink resources
- Add signing configuration using keystore
- Use gradle.properties for secure password storage
- Add keystore to .gitignore for security
2026-03-15 21:47:31 +08:00
ffb6677cfd fix: 修复自动导入照片功能,添加存储权限请求
- 添加READ_MEDIA_IMAGES和READ_EXTERNAL_STORAGE权限
- 实现权限请求逻辑,用户首次点击时请求权限
- 权限授予后自动导入最后N张照片
2026-03-11 21:32:54 +08:00
6165baa4c7 feat: 拼图功能增加自动导入最后N张照片功能
- 选择2x2模式时显示「自动导入最后4张照片」提示
- 选择3x3模式时显示「自动导入最后9张照片」提示
- 点击提示文字后自动从相册导入对应数量的最新照片
2026-03-11 19:28:16 +08:00
1d0cac0d1a fix: 调整拼图界面内容输入框高度为160dp
- 将内容输入框最小高度从200dp调整为160dp
- 保持5行文字的显示能力
- 优化界面空间利用率
2026-03-07 00:07:15 +08:00
306e479764 fix: 重构拼图界面布局,使用权重布局确保底部按钮始终可见
- 将内容区域包装在可滚动的Column中
- 使用weight(1f)让内容区域占据剩余空间
- 底部按钮固定在屏幕底部
- 保持内容输入框高度为200dp以显示5行文字
2026-03-06 23:59:06 +08:00
150e259205 fix: 增加拼图界面内容输入框高度,从150dp改为200dp,确保能完整显示5行文字 2026-03-06 23:53:31 +08:00
539b076fac Fix: increase content text field min height to 150dp for better 5-line display 2026-03-06 23:46:11 +08:00
97c701e691 Fix: adjust content text field height to display 5 lines fully in merge screen 2026-03-06 23:32:15 +08:00
df063dc38e Fix: dynamically position title/content input fields below image grid based on layout type 2026-03-06 23:10:08 +08:00
d0048c1d1c Add date/time to top of merged image - format: yyyy年M月d日 HH:mm:ss 2026-03-06 23:03:27 +08:00
9f1c6052e5 Fix: separate top title and bottom content in merge image - bottom content now dynamically positioned 2026-03-06 22:55:26 +08:00
a4d2e67fd6 Fix: properly load content from preferences in merge screen 2026-03-06 22:45:54 +08:00
16a32f6367 Add title at top of merged image - white bg with dark text 2026-03-06 22:36:59 +08:00
3dff4be357 Add title display area at top of merge screen - white bg with dark text 2026-03-06 22:21:56 +08:00
a082d76620 Fix: differentiate Default/Simple/Bold watermark styles - Simple now uses lighter bg with dark text 2026-03-06 22:00:59 +08:00
5e6b1b72b5 feat(settings): add save button and persist settings; refactor for recoder name; update UI texts 2026-03-06 19:10:23 +08:00
f53336b013 feat(setup): add Save button to Settings, persist all relevant prefs on click 2026-03-06 19:01:30 +08:00
6d83103b09 feat: 完善设置逻辑,添加记录人信息到水印,优化离线定位 2026-03-05 23:08:40 +08:00
917b69e2aa Fix: properly load title and content from preferences 2026-03-05 21:50:30 +08:00
20c29a9a57 Add dark background for date/location watermark, save/load title and content 2026-03-05 21:42:56 +08:00
a624dae001 Fix PuzzleMerge.kt: use maxOf instead of max 2026-03-05 21:14:25 +08:00
65adbee8b8 解决合并冲突,保留本地功能 2026-03-05 20:59:13 +08:00
6b051846fc 调整拼图内容区域起始位置 2026-03-05 20:57:40 +08:00
84d6a8fea9 更新README添加拼图布局技术规格 2026-03-03 22:11:03 +08:00
11521e29bd 添加拼图底部标题和内容区域 2026-03-02 22:58:58 +08:00
d2ec0c9b01 修改水印位置为底部中央 2026-03-02 22:24:00 +08:00
a7c6e6b909 feat: add airtest scripts for camera and gallery testing 2026-03-01 23:17:55 +08:00
44fe4d963c feat(puzzle merge): add 2x2 bitmap merge utility and UI integration; add AirTest test_puzzle_merge 2026-03-01 12:59:56 +08:00
0fe9ed4998 chore(ignore): ignore NUL file and common build outputs 2026-03-01 12:59:28 +08:00
1307 changed files with 3509 additions and 45949 deletions

61
.gitignore vendored
View File

@@ -1,5 +1,6 @@
# Built application files # Built application files
*.apk *.apk
*.aar
*.ap_ *.ap_
*.aab *.aab
@@ -13,6 +14,8 @@
bin/ bin/
gen/ gen/
out/ out/
build/
!app/build/outputs/apk/release/app-release.apk
# Gradle files # Gradle files
.gradle/ .gradle/
@@ -24,18 +27,17 @@ local.properties
# Proguard folder generated by Eclipse # Proguard folder generated by Eclipse
proguard/ proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder # Android Studio captures folder
captures/ captures/
# IntelliJ # IntelliJ
*.iml *.iml
.idea/ .idea/
misc.xml
deploymentTargetSelector.xml
markdown.xml
migrations.xml
runConfigurations.xml
# Keystore files # Keystore files
*.jks *.jks
@@ -45,7 +47,7 @@ captures/
.externalNativeBuild .externalNativeBuild
.cxx/ .cxx/
# Google Services (API key) # Google Services (e.g. APIs or Firebase)
google-services.json google-services.json
# Freeline # Freeline
@@ -53,19 +55,46 @@ freeline.py
freeline/ freeline/
freeline_project_description.json freeline_project_description.json
# fastjson # fastlane
fastjson/ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
# Test folder # Version control
test/ vcs.xml
tests/
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Android generated crash logs
crashlytics-build.properties
# Android Profiling
*.hprof
# Python # Python
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
# Airtest # AirTest
*.log airtest.log
*.png log.txt
report/ storage/
# Project specific
NUL
my-release.jks
app/my-release.jks
# 个别文件
需求表.md
push.bat
#测试文件
test*.py

Binary file not shown.

View File

@@ -1,2 +0,0 @@
#Sat Feb 28 12:39:22 CST 2026
gradle.version=8.2

View File

@@ -1,2 +0,0 @@
#Sat Feb 28 14:32:19 CST 2026
java.home=C\:\\Program Files\\Android\\Android Studio\\jbr

Binary file not shown.

1
.idea/.name generated
View File

@@ -1 +0,0 @@
InspectionCamera

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

18
.idea/gradle.xml generated
View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

8
.idea/markdown.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownSettings">
<option name="previewPanelProviderInfo">
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
</option>
</component>
</project>

10
.idea/migrations.xml generated
View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

10
.idea/misc.xml generated
View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

169
README.md
View File

@@ -1,42 +1,141 @@
# CheckShot - Android 图片检查与拼图工具 # 巡检相机 - Android 巡检图片处理工具
CheckShot 是一个面向 Android 的图片处理与检查工具,包含水印处理、拼图合成、以及丰富的设置能力,配合 AirTest 自动化测试用例,帮助实现端到端的图像工作流。 巡检相机是一个面向 Android 的巡检图片处理工具,包含水印处理、拼图合成、以及丰富的设置能力,配合 AirTest 自动化测试用例,帮助实现端到端的图像工作流。
核心功能 ## 软件界面截图
- 水印设置
- 时间水印:拍摄后在左下角叠加时间戳,格式固定为 "yyyy年-MM月-dd日 HH:mm:ss"。
- 地点水印:优先通过 Geocoder 联网解析地址,失败时回落显示经纬度。可在设置中配置校准方式。
- 样式:提供三种预设样式(默认/简约/醒目),并可在设置中预览和应用。
- 多图拼图(合成)模块
- 布局规则:支持 2x2 和 3x3 两种网格布局,图片自动缩放裁剪以适配网格。
- 核心能力:图片拼接、模板化布局编辑(替换/删除图片)、合成质量控制(分辨率/清晰度)。
- 交互:支持替换网格中的图片、删除图片、添加新图片、设置合成质量和文本水印文本。
- 设置与通用配置
- 水印设置、合成设置、通用设置、关于等配置项,均可通过设置界面调整。
- 测试与自动化
- 集成 AirTest 测试用例,覆盖水印、相册、拼图、设置等场景,便于回归验证。
架构与实现要点 启动应用后,可以看到以下主要界面:
- Watermark时间文本来自系统时间地点文本通过 LocationHelper/Geocoder 获取。
- Puzzle通过 Bitmap 拼接与 Canvas/Matrix 实现多种布局,支持图片替换、删除与质量控制。
- Settings使用 DataStore 保存用户偏好。
快速开始 ### 1. 相机界面
- 构建与运行 ![相机界面](相机.png)
- 构建调试 APK`./gradlew assembleDebug`
- 在设备/模拟器上安装:`adb install -r app/build/outputs/apk/debug/app-debug.apk`
- AirTest 测试
- 运行测试用例(需安装 AirTest 及依赖):`airtest run test/airtest/... --device Android:///`
项目结构与升级 *主相机界面,支持拍照、自动/手动对焦、曝光调节,拍摄后自动叠加水印*
- 主要代码位于:
- app/src/main/... 业务代码与 UI 组件
- app/src/test/... 单元测试
- test/airtest/... AirTest 的 UI 测试用例
- README 作为版本演进的记录,后续变更请同步更新。
持续集成与发布 ### 2. 相册界面
- 建议在 CI 中执行编译、单元测试、AirTest 测试并在通过后打包发行版。 ![相册界面](相册.png)
联系与贡献 *相册管理界面,支持本地存储、分类管理、预览、导出/分享*
- 如需进一步定制文档结构,或需要将某些部分拆分为单独的开发指南,请告知偏好。
### 3. 拼图界面
![拼图界面](拼图.png)
*多图拼图合成界面,支持 2x2 和 3x3 网格布局*
### 4. 设置界面
![设置界面](设置.png)
*应用设置界面,支持水印样式、地点获取方式、合成布局、图片质量、文件名模板、记录人信息等配置*
## 功能特点
- **相机模块**:✅ 使用 CameraX 库实现拍照、自动/手动对焦、曝光调节,拍摄后自动叠加水印(时间 + 地点)
- **水印处理**:✅ 支持时间水印(格式固定为 "yyyy 年 MM 月 d 日 HH:mm:ss")和地点水印(优先联网解析,失败时显示经纬度),提供三种预设样式(默认/简约/醒目)
- **EXIF 元数据**:✅ 自动写入 GPS 坐标、拍摄时间、相机型号、作者信息到照片 EXIF
- **多图拼图(合成)模块**:✅ 支持 2x2、1x3、3x1 等多种网格布局,图片自动缩放裁剪,支持图片替换、删除、添加和质量控制(高/标准/低)
- **文字编辑模块**:✅ 在合成图片的顶部(标题 + 日期时间)和底部(内容 + 记录人)添加带背景的文字说明,支持智能换行
- **图片管理**:✅ 本地存储、按日期分组查看(今天/昨天/上月/更早)、预览、删除、导出/分享
- **文件名模板**:✅ 支持自定义文件名格式,可用占位符:`{project}` `{device}` `{inspector}` `{date}` `{time}`
- **设置与通用配置**:✅ 水印样式、地点获取方式(网络/GPS、合成布局、图片质量、文件名模板、记录人信息等均可配置
- **测试与自动化**:✅ 集成 AirTest 测试用例 + JUnit 单元测试,覆盖拼图等场景
## 安装步骤
1. **克隆项目**
```bash
git clone http://124.223.26.33:3000/xiaji/anroid-CheckShot.git
cd anroid-CheckShot
```
2. **构建调试 APK**
```bash
./gradlew assembleDebug
```
3. **安装到设备**
```bash
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
4. **安装 AirTest 依赖(用于测试)**
```bash
pip install airtest pocoui
```
## 使用示例
### 基本使用
1. **启动应用**:在 Android 设备/模拟器上安装并打开巡检相机
2. **拍照**:点击相机按钮拍照,自动添加水印
3. **拼图**:选择多张图片进行拼图合成
4. **查看相册**:浏览和管理拍摄的照片
### 构建发布 APK
```bash
# 构建签名 APK需配置好 keystore
./gradlew assembleRelease
# 构建产物位置
app/build/outputs/apk/release/app-release.apk
```
### 运行测试
```bash
# 确保设备已连接
adb devices
# 运行 AirTest 拼图测试
airtest run test/airtest/test_puzzle_merge.py --device Android:///
# 运行手动测试脚本
python test_android.py # 基础功能测试
python test_camera.py # 相机功能测试
python test_gallery.py # 相册功能测试
```
## 目录结构
```
anroid-CheckShot/
├── app/ # App 模块
│ ├── src/main/ # 主代码
│ │ ├── java/ # Kotlin/Java 代码
│ │ └── res/ # 资源文件
│ ├── build.gradle.kts # App 级构建配置
│ └── my-release.jks # 签名密钥(本地)
├── test/ # 测试代码
│ └── airtest/ # AirTest UI 测试
├── gradle.properties # Gradle 属性(含签名配置)
├── build.gradle.kts # 项目级构建配置
├── settings.gradle.kts # 项目设置
└── README.md # 项目说明
```
## 贡献指南
1. Fork 项目仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 提交 Pull Request
## 常见问题 (FAQ)
**Q: 如何修改水印样式?**
A: 在设置界面中选择水印样式(默认/简约/醒目),可实时预览效果。
**Q: AirTest 测试失败怎么办?**
A: 确保设备已连接且已安装 AirTest 依赖,检查设备是否开启开发者选项和 USB 调试。
**Q: 拼图功能支持哪些布局?**
A: 支持 2x2、1x3、3x1 等多种网格布局,图片会自动缩放裁剪以适配网格。
**Q: 如何自定义文件名格式?**
A: 在设置界面的"文件名模板"中编辑,支持占位符:`{project}`(项目)、`{device}`(设备 ID、`{inspector}`(记录人)、`{date}`(日期)、`{time}`(时间)。
## 联系方式/反馈渠道
- 问题反馈:请在仓库中提交 Issue
- 代码贡献:欢迎提交 Pull Request

View File

@@ -20,13 +20,24 @@ android {
} }
} }
signingConfigs {
create("release") {
storeFile = file(project.properties["RELEASE_STORE_FILE"] as String? ?: "my-release.jks")
storePassword = project.properties["RELEASE_STORE_PASSWORD"] as String? ?: "android123"
keyAlias = project.properties["RELEASE_KEY_ALIAS"] as String? ?: "my-key"
keyPassword = project.properties["RELEASE_KEY_PASSWORD"] as String? ?: "android123"
}
}
buildTypes { buildTypes {
release { release {
isMinifyEnabled = false isMinifyEnabled = false
isShrinkResources = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"
) )
signingConfig = signingConfigs.getByName("release")
} }
} }
compileOptions { compileOptions {
@@ -49,7 +60,7 @@ android {
} }
lint { lint {
abortOnError = false abortOnError = false
checkReleaseBuilds = true checkReleaseBuilds = false
warningsAsErrors = false warningsAsErrors = false
} }
} }
@@ -89,6 +100,9 @@ dependencies {
// Accompanist permissions // Accompanist permissions
implementation("com.google.accompanist:accompanist-permissions:0.32.0") implementation("com.google.accompanist:accompanist-permissions:0.32.0")
// ExifInterface
implementation("androidx.exifinterface:exifinterface:1.3.7")
// Testing // Testing
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.ext:junit:1.1.5")

View File

@@ -1,2 +0,0 @@
#- File Locator -
listingFile=../../../outputs/apk/debug/output-metadata.json

View File

@@ -1,2 +0,0 @@
appMetadataVersion=1.1
androidGradlePluginVersion=8.2.0

View File

@@ -1,10 +0,0 @@
{
"version": 3,
"artifactType": {
"type": "COMPATIBLE_SCREEN_MANIFEST",
"kind": "Directory"
},
"applicationId": "com.inspection.camera",
"variantName": "debug",
"elements": []
}

Some files were not shown because too many files have changed in this diff Show More