English | 中文
SnapSolver is an image similarity-based question-solving application. Users can take or select question images, and the system will automatically search for similar questions and display corresponding answers.
SnapSolver 是一个基于图像相似度搜索的题目解答应用。用户可以通过拍摄或选择题目图片,系统会自动搜索相似的题目并显示对应的答案。
- 📸 Camera Recognition / 拍照识别:Take photos of questions using the camera / 使用相机拍摄题目照片
- 🖼️ Photo Library Selection / 相册选择:Select question images from photo library / 从相册中选择题目图片
- ✂️ Smart Cropping / 智能裁剪:Manually adjust cropping area for precise question recognition / 支持手动调整裁剪区域,精确识别题目
- 🔍 Similarity Search / 相似度搜索:Fast question matching based on Ximilar image similarity API / 基于 Ximilar 图像相似度 API 快速匹配题目
- 📚 Answer Display / 答案展示:Automatically display original questions and answer images for matched questions / 自动显示匹配题目的原题和答案图片
- 🌐 Cloud Storage / 云端存储:Store questions and answers using Cloudflare R2 / 使用 Cloudflare R2 存储题目和答案图片
SnapSolver/
├── SnapSolver/ # iOS Application Main Directory / iOS 应用主目录
│ ├── SnapSolverApp.swift # App Entry Point / App 入口
│ ├── Views/ # View Layer / 视图层
│ │ ├── HomeView.swift # Home Page (Camera/Photo Selection) / 首页(拍照/相册选择)
│ │ ├── CropView.swift # Image Cropping Page / 图片裁剪页面
│ │ ├── ResultView.swift # Results Display Page / 结果展示页面
│ │ ├── CustomCameraView.swift # Custom Camera View / 自定义相机视图
│ │ └── ImageViewer.swift # Image Viewer / 图片查看器
│ ├── ViewModels/ # View Model Layer / 视图模型层
│ │ ├── SnapSolverViewModel.swift
│ │ └── ResultViewModel.swift
│ ├── Services/ # Service Layer / 服务层
│ │ └── XimilarClient.swift # Ximilar API Client / Ximilar API 客户端
│ ├── Models/ # Data Models / 数据模型
│ │ └── XimilarResponse.swift
│ ├── Config/ # Configuration Files / 配置文件
│ │ ├── XimilarConfig.swift # Ximilar Configuration / Ximilar 配置
│ │ └── R2Config.swift # R2 Configuration / R2 配置
│ └── Utils/ # Utility Classes / 工具类
│ ├── ImagePreprocessor.swift
│ └── R2ImageURLBuilder.swift
├── exam-mate/ # Question Scraper Scripts / 题目爬虫脚本
│ └── exam-mate.py # Scrape questions from exam-mate.com / 从 exam-mate.com 爬取题目
├── PY/ # Python Utility Scripts / Python 工具脚本
│ ├── merge_images.py # Merge Split Images / 合并分片图片
│ ├── upload_to_ximilar.py # Upload Questions to Ximilar / 上传题目到 Ximilar
│ ├── upload_to_r2.py # Upload Images to R2 / 上传图片到 R2
│ ├── count_r2.py # Count R2 Files / 统计 R2 文件数量
│ └── msyh.ttf # Chinese Font File / 中文字体文件
└── 添加题目说明.md # Question Addition Guide / 添加题目的详细说明
- macOS 12.0 or higher / macOS 12.0 或更高版本
- Xcode 14.0 or higher / Xcode 14.0 或更高版本
- iOS 15.0 or higher (target device) / iOS 15.0 或更高版本(目标设备)
- Swift 5.7+
- Python 3.7 or higher / Python 3.7 或更高版本
- Required Python packages / 必需的 Python 包:
pip install requests pyquery pandas pillow openpyxl boto3
git clone https://github.com/yourusername/SnapSolver.git
cd SnapSolverStep 1: Create Ximilar Account / 步骤 1:创建 Ximilar 账号
- Visit Ximilar Website / 访问 Ximilar 官网
- Register and log in / 注册并登录账号
- Go to Dashboard / 进入 Dashboard
Step 2: Create Photo Similarity Collection / 步骤 2:创建 Photo Similarity Collection
- In Ximilar Dashboard, click "Visual Search" or "Image Similarity" / 在 Ximilar Dashboard 中,点击 "Visual Search" 或 "Image Similarity"
- Select "Photo Similarity (NEW)" type / 选择 "Photo Similarity (NEW)" 类型
- Click "Create Collection" / 点击 "Create Collection"
- Enter Collection name (e.g.,
SnapSolver Questions) / 填写 Collection 名称(例如:SnapSolver Questions) - After creation, copy the Collection ID (format:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) / 创建完成后,复制 Collection ID(格式类似:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
Step 3: Get API Token / 步骤 3:获取 API Token
- In Ximilar Dashboard, go to Settings → API Tokens / 在 Ximilar Dashboard 中,进入 Settings → API Tokens
- Click "Create New Token" / 点击 "Create New Token"
- Copy the generated API Token (format:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) / 复制生成的 API Token(格式类似:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Step 4: Configure iOS Application / 步骤 4:配置 iOS 应用
Edit SnapSolver/Config/XimilarConfig.swift:
static let apiToken = "YOUR_XIMILAR_API_TOKEN_HERE"
static let collectionId = "YOUR_COLLECTION_ID_HERE"Step 5: Configure Python Scripts / 步骤 5:配置 Python 脚本
Edit PY/upload_to_ximilar.py:
API_TOKEN = "YOUR_XIMILAR_API_TOKEN_HERE"
COLLECTION_ID = "YOUR_COLLECTION_ID_HERE"Step 1: Create Cloudflare Account / 步骤 1:创建 Cloudflare 账号
- Visit Cloudflare Website / 访问 Cloudflare 官网
- Register and log in / 注册并登录账号
Step 2: Create R2 Bucket / 步骤 2:创建 R2 Bucket
- In Cloudflare Dashboard, click R2 / 在 Cloudflare Dashboard 中,点击 R2
- Click "Create bucket" / 点击 "Create bucket"
- Enter Bucket name (e.g.,
snapsolver) / 输入 Bucket 名称(例如:snapsolver) - Select region (recommend choosing the nearest region) / 选择区域(建议选择离你最近的区域)
- After creation, record the Bucket Name / 创建完成后,记录 Bucket 名称
Step 3: Create R2 API Token / 步骤 3:创建 R2 API Token
- On R2 page, click "Manage R2 API Tokens" / 在 R2 页面,点击 "Manage R2 API Tokens"
- Click "Create API Token" / 点击 "Create API Token"
- Select permissions / 选择权限:
- Object Read & Write (for uploading images) / Object Read & Write(用于上传图片)
- Select the Bucket to access / 选择要访问的 Bucket
- After creation, copy the following information / 创建完成后,复制以下信息:
- Access Key ID
- Secret Access Key
Step 4: Get Account ID / 步骤 4:获取 Account ID
- In Cloudflare Dashboard right sidebar, find Account ID / 在 Cloudflare Dashboard 右侧边栏,找到 Account ID
- Copy Account ID / 复制 Account ID
Step 5: Configure Public Access (Optional) / 步骤 5:配置公开访问(可选)
If you need to access images directly via URL / 如果需要通过 URL 直接访问图片:
- In R2 Bucket settings, find Public Access / 在 R2 Bucket 设置中,找到 Public Access
- You can bind a custom domain or use Cloudflare's Public Development URL / 可以绑定自定义域名,或使用 Cloudflare 提供的 Public Development URL
- Record the public access URL (e.g.,
https://your-bucket.your-domain.comorhttps://xxxxx.r2.dev) / 记录公开访问的 URL(例如:https://your-bucket.your-domain.com或https://xxxxx.r2.dev)
Step 6: Configure Python Scripts / 步骤 6:配置 Python 脚本
Edit PY/upload_to_r2.py:
ACCOUNT_ID = "YOUR_CLOUDFLARE_ACCOUNT_ID_HERE"
ACCESS_KEY_ID = "YOUR_R2_ACCESS_KEY_ID_HERE"
SECRET_ACCESS_KEY = "YOUR_R2_SECRET_ACCESS_KEY_HERE"
BUCKET_NAME = "YOUR_BUCKET_NAME_HERE"Step 7: Configure iOS Application / 步骤 7:配置 iOS 应用
Edit SnapSolver/Config/R2Config.swift:
static let baseURL = URL(string: "YOUR_R2_PUBLIC_URL_HERE")!Open the project in Xcode / 在 Xcode 中打开项目:
- Select Project → Target → Info / 选择项目 → Target → Info
- Add the following permission descriptions / 添加以下权限说明:
- Privacy - Camera Usage Description: "需要访问相机以拍摄题目照片" / "Need camera access to take question photos"
- Privacy - Photo Library Usage Description: "需要访问相册以选择题目照片" / "Need photo library access to select question images"
Or directly edit Info.plist / 或者直接编辑 Info.plist:
<key>NSCameraUsageDescription</key>
<string>需要访问相机以拍摄题目照片</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择题目照片</string>-
Open Project / 打开项目
# If you've already cloned the project, navigate to the project directory # 如果已经克隆了项目,直接进入项目目录 cd SnapSolver # Open Xcode project # 打开 Xcode 项目 open SnapSolver.xcodeproj
-
Select Run Target / 选择运行目标
- In Xcode top toolbar, select target device / 在 Xcode 顶部工具栏,选择目标设备:
- Physical device (requires Apple Developer account) / 真机设备(需要 Apple Developer 账号)
- iOS Simulator (recommended for testing) / iOS Simulator(推荐用于测试)
- In Xcode top toolbar, select target device / 在 Xcode 顶部工具栏,选择目标设备:
-
Run Application / 运行应用
- Press
Cmd + Ror click Run button / 按Cmd + R或点击运行按钮 - Wait for compilation to complete, app will launch automatically / 等待编译完成,应用会自动启动
- Press
-
Install Dependencies / 安装依赖
cd PY pip install -r requirements.txtIf
requirements.txtdoesn't exist, install manually / 如果没有requirements.txt,手动安装:pip install requests pyquery pandas pillow openpyxl boto3
-
Run Scraper Script / 运行爬虫脚本
cd ../exam-mate python exam-mate.py -
Merge Images / 合并图片
cd ../PY python merge_images.py -
Upload Images / 上传图片
# Upload to Ximilar (questions only) # 上传到 Ximilar(只上传题目) python upload_to_ximilar.py # Upload to R2 (answers first, then questions) # 上传到 R2(先上传答案,再上传题目) python upload_to_r2.py # First time: answers / 第一次:答案 # Modify R2_KEY_PREFIX in upload_to_r2.py to "questions" # 修改 upload_to_r2.py 中的 R2_KEY_PREFIX 为 "questions" python upload_to_r2.py # Second time: questions / 第二次:题目
For detailed instructions, please refer to 添加题目说明.md / 详细说明请参考 添加题目说明.md
Brief process / 简要流程:
- Configure Cookie / 配置 Cookie:Set your exam-mate.com Cookie in
exam-mate/exam-mate.py/ 在exam-mate/exam-mate.py中设置你的 exam-mate.com Cookie - Set URL / 设置 URL:Set target question URL in
exam-mate/exam-mate.py/ 在exam-mate/exam-mate.py中设置目标题目的 URL - Run Scraper / 运行爬虫:Execute
python exam-mate/exam-mate.pyto download questions and answers / 执行python exam-mate/exam-mate.py下载题目和答案 - Organize Files / 整理文件:Rename and move downloaded
questionandanswerfolders tobank/directory / 将下载的question和answer文件夹重命名并移动到bank/目录 - Merge Images / 合并图片:Run
python PY/merge_images.pyto merge split images / 运行python PY/merge_images.py合并分片图片 - Upload Images / 上传图片:Upload to Ximilar and R2 separately / 分别上传到 Ximilar 和 R2
- API Token:Used for authentication / 用于身份验证
- Collection ID:Image similarity search collection ID / 图片相似度搜索的集合 ID
- Base URL:
https://api.ximilar.com/similarity/photos/v2(fixed) / (固定)
- Account ID:Cloudflare account ID / Cloudflare 账号 ID
- Access Key ID:R2 API access key ID / R2 API 访问密钥 ID
- Secret Access Key:R2 API secret key / R2 API 密钥
- Bucket Name:R2 bucket name / R2 存储桶名称
- Public URL:Public access URL (for iOS app to load images) / 公开访问 URL(用于 iOS 应用加载图片)
- Launch App / 启动应用:Open SnapSolver / 打开 SnapSolver
- Select Image / 选择图片:
- Click "Take Photo" button to use camera / 点击 "拍照" 按钮使用相机拍摄
- Click "Photo Library" button to select from album / 点击 "相册" 按钮从相册选择
- Crop Question / 裁剪题目:Adjust rectangle frame on cropping page to select question area / 在裁剪页面调整矩形框,选择题目区域
- Search Match / 搜索匹配:After clicking confirm, system automatically searches for similar questions / 点击确认后,系统自动搜索相似题目
- View Answer / 查看答案:View matched questions and answers on results page / 在结果页面查看匹配的题目和答案
- exam-mate.py:Scrape questions from exam-mate.com / 从 exam-mate.com 爬取题目
- merge_images.py:Merge split question/answer images / 合并分片的题目/答案图片
- upload_to_ximilar.py:Upload question images to Ximilar / 上传题目图片到 Ximilar
- upload_to_r2.py:Upload images to Cloudflare R2 / 上传图片到 Cloudflare R2
-
iOS Application / iOS 应用:
- SwiftUI
- Swift 5.7+
- Async/Await
- URLSession
-
Python Scripts / Python 脚本:
- requests (HTTP requests) / requests(HTTP 请求)
- pyquery (HTML parsing) / pyquery(HTML 解析)
- PIL/Pillow (image processing) / PIL/Pillow(图片处理)
- boto3 (AWS S3 compatible API for R2) / boto3(AWS S3 兼容 API,用于 R2)
-
Third-party Services / 第三方服务:
- Ximilar (image similarity search) / Ximilar(图像相似度搜索)
- Cloudflare R2 (object storage) / Cloudflare R2(对象存储)
- API Quota / API 配额:Pay attention to free quota limits for Ximilar and Cloudflare R2 / 注意 Ximilar 和 Cloudflare R2 的免费配额限制
- Network Connection / 网络连接:App requires network connection to search questions / 应用需要网络连接才能搜索题目
- Image Format / 图片格式:Supports common image formats like PNG, JPEG / 支持 PNG、JPEG 等常见图片格式
- Privacy Protection / 隐私保护:Do not commit API keys to Git repository / 不要将 API 密钥提交到 Git 仓库
- Cookie Expiration / Cookie 有效期:exam-mate.com cookies may expire, need to update regularly / exam-mate.com 的 Cookie 可能过期,需要定期更新
Welcome to submit Issues and Pull Requests! / 欢迎提交 Issue 和 Pull Request!
This project is licensed under the MIT License. See LICENSE file for details. / 本项目采用 MIT 许可证。详见 LICENSE 文件。
For questions or suggestions, please contact via GitHub Issues. / 如有问题或建议,请通过 GitHub Issues 联系。
Last Updated / 最后更新:January 2025 / 2025年1月