Skip to content

Commit 0b8d15d

Browse files
committed
QuickView: 复制位图=窗口大小(Picasa 所见即所得)+ 双击进 Manager + README 卖点
- Ctrl+C 位图尺寸 = 当前窗口(非固定 1600)——超大图粘贴聊天软件不爆上限 - 双击图片 → 启动 Manager(传当前文件夹);Manager exe 复制到 QuickView 同目录 - README/EN 加 QuickView 卖点(HDR/超小/秒开/极简/复制位图/校准/插件)
1 parent 4ad3378 commit 0b8d15d

3 files changed

Lines changed: 92 additions & 11 deletions

File tree

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,36 @@ QLens 管"怎么打标签"(执行),把"打完标签干什么"(玩法)
5959
6060
---
6161

62+
## QuickView(qlens_quickview)
63+
64+
**当前主力看图器**——原生 Win32 + D3D11,无 Qt 依赖,exe 仅 **~160KB**
65+
66+
### 卖点
67+
68+
| 卖点 | 说明 |
69+
|------|------|
70+
| **真 HDR 支持** | 16F 全精度直通管线——JXR/高位深 HEIC/AVIF 的 HDR 亮度正确显示(1.0=80nit scRGB 物理标准),SDR 图有 SDR→HDR 上转换增强 |
71+
| **超小** | 单个 exe ~160KB,无 Qt/无运行时依赖(WIC 解码 + 系统 DLL) |
72+
| **秒开** | 原生 Win32 极简架构,启动即看,无加载动画 |
73+
| **极简但够用** | 缩放/翻页/缩略图导航条/旋转/复制/另存为/删除/右键菜单/全屏——一个看图器该有的都有,不堆砌 |
74+
| **Picasa 式复制** | `Ctrl+C` 位图 = **当前窗口大小**(所见即所得)——超大图粘贴到 QQ/微信等聊天软件不爆位图大小上限;同时提供文件(CF_HDROP)+ 路径(CF_UNICODETEXT)格式 |
75+
| **HDR 校准** | 内置 `gen_hdrtest.exe` 生成 0-10000nit 分区块测试图——客户可验证显示器真实 HDR 峰值 |
76+
| **插件扩展** | 解码插件(HEIC/SVG 等)动态加载,新格式随时加 DLL 支持 |
77+
78+
### 快捷键
79+
80+
```
81+
滚轮 翻页(Ctrl+滚轮 缩放)
82+
←/→ 上一张/下一张
83+
F / S 100% 原尺寸 / 窗口适配
84+
Q / E 左旋转 / 右旋转
85+
Ctrl+C 复制(位图=窗口大小 + 文件 + 路径)
86+
Ctrl+Shift+S 另存为
87+
Del 删除到回收站
88+
F12 DEBUG 信息(格式/显示器/HDR 状态)
89+
--monitor N 指定启动显示器
90+
```
91+
6292
## 组件
6393

6494
| 组件 | 说明 |

README_EN.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,36 @@ QLens owns *how tags get written* (execution); *what you do with tagged photos*
7272
7373
---
7474

75+
## QuickView (qlens_quickview)
76+
77+
**Current primary image viewer** — native Win32 + D3D11, no Qt dependency, exe only **~160KB**.
78+
79+
### Highlights
80+
81+
| Feature | Description |
82+
|---------|-------------|
83+
| **True HDR support** | 16F full-precision passthrough pipeline — JXR/high-bitdepth HEIC/AVIF HDR brightness displayed correctly (1.0=80nit scRGB physical standard), SDR images get SDR→HDR upconversion |
84+
| **Ultra small** | Single exe ~160KB, no Qt/runtime dependency (WIC decode + system DLLs) |
85+
| **Instant launch** | Native Win32 minimalist architecture, opens immediately |
86+
| **Minimal but complete** | Zoom/page/thumbnail strip/rotate/copy/save-as/delete/context menu/fullscreen — everything a viewer needs, nothing more |
87+
| **Picasa-style copy** | `Ctrl+C` bitmap = **current window size** (what-you-see-is-what-you-get) — pasting huge images into QQ/WeChat etc. won't blow the bitmap size limit; also provides file (CF_HDROP) + path (CF_UNICODETEXT) formats |
88+
| **HDR calibration** | Built-in `gen_hdrtest.exe` generates 0-10000nit block test image — customers can verify their monitor's real HDR peak |
89+
| **Plugin extension** | Decode plugins (HEIC/SVG etc.) dynamically loaded — new formats supported by adding a DLL |
90+
91+
### Shortcuts
92+
93+
```
94+
Wheel Page (Ctrl+Wheel = zoom)
95+
←/→ Previous/next
96+
F / S 100% original / fit window
97+
Q / E Rotate left/right
98+
Ctrl+C Copy (bitmap=window size + file + path)
99+
Ctrl+Shift+S Save as
100+
Del Delete to recycle bin
101+
F12 DEBUG info (format/monitor/HDR state)
102+
--monitor N Start on specified monitor
103+
```
104+
75105
## Components
76106

77107
| Component | Description |

src/quickview/window.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,30 @@ static void LoadDirFiles(const std::wstring &path)
162162
if (_wcsicmp(a.c_str(), b.c_str()) == 0) { g_curIdx = (int)i; break; }
163163
}
164164
}
165+
// 启动 Manager(exe 同目录 qlens_manager.exe;传当前文件夹路径)
166+
static void LaunchManager(HWND hwnd)
167+
{
168+
wchar_t exe[MAX_PATH];
169+
GetModuleFileNameW(nullptr, exe, MAX_PATH);
170+
wchar_t dir[MAX_PATH];
171+
wcscpy_s(dir, exe);
172+
PathRemoveFileSpecW(dir);
173+
std::wstring mgr = std::wstring(dir) + L"\\qlens_manager.exe";
174+
// 传当前图片所在文件夹
175+
std::wstring arg;
176+
if (!g_curFile.empty()) {
177+
wchar_t folder[MAX_PATH];
178+
wcscpy_s(folder, g_curFile.c_str());
179+
PathRemoveFileSpecW(folder);
180+
arg = L"\"" + std::wstring(folder) + L"\"";
181+
}
182+
ShellExecuteW(nullptr, L"open", mgr.c_str(), arg.empty() ? nullptr : arg.c_str(), nullptr, SW_SHOWNORMAL);
183+
}
184+
165185
void LoadFileByPath(HWND hwnd, const wchar_t *path)
166186
{
167187
if (hwnd) g_hwnd = hwnd;
168-
g_curFile = path;
169-
LoadDirFiles(path);
188+
g_curFile = path; LoadDirFiles(path);
170189
RendererEnsureInit(g_hwnd);
171190
StartAnimationIfGif(g_curFile);
172191
RequestLoadAsync(g_curFile);
@@ -264,9 +283,11 @@ static void CopyCurrentImage()
264283
{
265284
DecodedImage img;
266285
if (DecodeImageFile(g_curFile, img) && img.width > 0 && img.height > 0) {
267-
// 若最长边 > 1600,降采样(Picasa 风格:粘贴 QQ 不爆大小
286+
// 位图 = 当前窗口大小(所见即所得,Picasa 风格——避免超大图爆掉聊天软件位图粘贴上限
268287
int w = img.width, h = img.height;
269-
const int MAX_SIDE = 1600;
288+
int winW = 0, winH = 0;
289+
if (g_hwnd) { RECT rc; if (GetClientRect(g_hwnd, &rc)) { winW = rc.right; winH = rc.bottom; } }
290+
const int MAX_SIDE = (winW > 0 && winH > 0) ? (winW > winH ? winW : winH) : 1600;
270291
std::vector<unsigned char> buf; // compressed BGRA pixels
271292
if (w > MAX_SIDE || h > MAX_SIDE) {
272293
float scale = (float)MAX_SIDE / (w > h ? w : h);
@@ -615,6 +636,11 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
615636
}
616637
}
617638
return 0;
639+
case WM_LBUTTONDBLCLK: {
640+
// 双击进 Manager(打开当前图片所在文件夹)
641+
LaunchManager(hwnd);
642+
return 0;
643+
}
618644
case WM_LBUTTONDOWN: {
619645
int x = (short)LOWORD(lp), y = (short)HIWORD(lp);
620646
RECT rc; GetClientRect(hwnd, &rc);
@@ -624,13 +650,8 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
624650
if (btn == 1) { if (g_curIdx > 0) NavTo(g_curIdx - 1, hwnd); return 0; }
625651
if (btn == 2) { if (g_curIdx < (int)g_files.size()-1) NavTo(g_curIdx + 1, hwnd); return 0; }
626652
if (btn == 3) {
627-
// 启动 Manager
628-
wchar_t exe[MAX_PATH];
629-
GetModuleFileNameW(nullptr, exe, MAX_PATH);
630-
wchar_t dir[MAX_PATH];
631-
wcscpy_s(dir, exe);
632-
PathRemoveFileSpecW(dir);
633-
ShellExecuteW(nullptr, L"open", (std::wstring(dir) + L"\\qlens_manager.exe").c_str(), nullptr, nullptr, SW_SHOWNORMAL);
653+
// 启动 Manager(复用 LaunchManager)
654+
LaunchManager(hwnd);
634655
return 0;
635656
}
636657
int idx = g_strip.hitTest(x, y, rc.bottom);

0 commit comments

Comments
 (0)