Skip to content

Task #938: 복학원서 JPEG 워터마크 배경 사각형 제거 및 톤 보정#976

Closed
postmelee wants to merge 1 commit into
edwardkim:develfrom
postmelee:codex/issue-938-watermark
Closed

Task #938: 복학원서 JPEG 워터마크 배경 사각형 제거 및 톤 보정#976
postmelee wants to merge 1 commit into
edwardkim:develfrom
postmelee:codex/issue-938-watermark

Conversation

@postmelee

@postmelee postmelee commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Refs #938

문제

samples/복학원서.hwp의 중앙 JPEG 워터마크가 rhwp SVG / WebCanvas / rhwp-studio overlay 경로에서 큰 회색 사각형 배경처럼 보입니다.

원본 JPEG에는 alpha 채널이 없고 near-white 배경 픽셀이 포함되어 있습니다. 기존 렌더러는 이 JPEG 전체에 밝기/대비 보정, opacity, blend 처리를 적용했기 때문에 워터마크 문양뿐 아니라 JPEG 배경 영역까지 함께 보정되어 사각형 흔적이 남았습니다.

원인

한컴 PDF 출력 결과는 JPEG 원본에 SVG/CSS 필터를 실시간 적용한 결과라기보다, 워터마크 톤을 흰 배경 위에 미리 합성한 opaque 이미지에 가깝습니다.

따라서 기존처럼 JPEG 전체를 반투명 필터 이미지로 취급하면 다음 차이가 생깁니다.

  • near-white 배경 픽셀도 필터/opacity 대상이 되어 회색 사각형이 남음
  • SVG 렌더러와 rhwp-studio overlay가 서로 다른 필터 경로를 타며 톤 차이가 커짐
  • WASM overlay 경로에서는 JPEG decode feature가 없어 동일 보정을 적용하기 어려움

수정

워터마크성 JPEG에 한해 한컴 출력에 가까운 opaque PNG로 미리 bake한 뒤, 모든 렌더 경로가 이 baked PNG를 사용하도록 맞췄습니다.

  • src/renderer/svg.rs
    • PicEffect != RealPic, 밝기/대비 보정값, JPEG MIME/시그니처, near-white 배경 비율을 함께 확인해 워터마크성 JPEG만 감지
    • near-white 픽셀은 opaque white로 유지
    • 비흰색 워터마크 픽셀은 한컴 PDF 참고 렌더에 가까운 gray ramp로 변환
    • baked PNG에는 기존 SVG 필터와 opacity=0.17을 다시 적용하지 않음
  • src/document_core/queries/rendering.rs
    • overlay image JSON에 bakedWatermark: true 추가
    • overlay 경로에서도 동일한 baked PNG data URL을 반환
  • src/renderer/web_canvas.rs
    • WebCanvas 직접 렌더 경로도 baked PNG를 사용하고 중복 필터 적용을 생략
  • rhwp-studio/src/view/page-renderer.ts
    • bakedWatermark overlay는 CSS filter, mix-blend-mode, opacity를 적용하지 않음
  • Cargo.toml
    • WASM에서도 JPEG decode가 가능하도록 image crate feature에 jpeg 추가
  • 테스트
    • tests/issue_938.rs 추가
    • tests/issue_514.rs의 JPEG 워터마크 기대값 갱신
    • tests/golden_svg/issue-677/bokhakwonseo-page1.svg 갱신

시각 비교

아래 이미지는 PR 작성 후 수동 첨부 예정입니다. 한컴 PDF는 CONTRIBUTING 안내에 따라 절대 기준이 아니라 참고 렌더로 사용합니다.

작업 전 렌더 (upstream/devel) 작업 후 렌더 (이 PR) 한컴 PDF (복학원서-2022.pdf)
image image reference-answer

검증

통과:

  • cargo test --release --test issue_938 --test issue_514 --test issue_516 --test svg_snapshot
  • cargo check --target wasm32-unknown-unknown --release --lib
  • npm run build (rhwp-studio)
  • git diff --cached --check

확인했지만 통과하지 않은 항목:

  • cargo test --release --lib
    • 결과: 1296 passed / 1 failed / 2 ignored
    • 실패 테스트: renderer::layout::integration_tests::tests::test_548_cell_inline_shape_first_line_indent_p8
    • 이번 PR은 해당 layout 테스트가 의존하는 배치 로직 파일을 수정하지 않습니다.
  • cargo clippy --release --lib -- -D warnings
    • 실패 위치: src/diagnostics/hwp5_contract_probe.rs:366
    • lint: clippy::unnecessary_unwrap
    • 이번 PR에서 수정하지 않은 기존 diagnostics 코드입니다.

리뷰 포인트

  • 워터마크 판별 조건을 의도적으로 좁게 두었습니다. 일반 JPEG/PNG/PCX 이미지에는 기존 경로가 유지됩니다.
  • baked PNG는 opaque 출력입니다. 투명 PNG로 만드는 방식도 검토했지만, 한컴 PDF 참고 렌더와 톤이 더 벌어져 최종안에서 제외했습니다.
  • 중앙 워터마크 위치에는 아직 작은 차이가 남아 있습니다. 이 PR은 파일별 위치 보정을 넣지 않고, #938의 배경 사각형/톤 문제만 처리합니다.
  • 다른 워터마크 파일을 테스트하면서 발견한 PageBackground/fill-mode 문제는 별도 이슈 PageBackground 이미지 fill_mode(Center 등)가 전체 페이지 늘림으로 렌더링됨 #975 로 분리했습니다.

@postmelee postmelee changed the title [codex] Fix #938: JPEG 워터마크 톤 보정 Task #938: 복학원서 JPEG 워터마크 배경 사각형 제거 및 톤 보정 May 18, 2026
@postmelee postmelee force-pushed the codex/issue-938-watermark branch from b8651c9 to 34615a6 Compare May 18, 2026 01:10
@postmelee postmelee force-pushed the codex/issue-938-watermark branch from 34615a6 to 2a48ed3 Compare May 18, 2026 01:20
@postmelee postmelee marked this pull request as ready for review May 18, 2026 01:28
edwardkim pushed a commit that referenced this pull request May 19, 2026
- cherry-pick 7a1f22f 검증: test 1484 passed, clippy 0, fmt 0, WASM ok
- 시각 판정 통과 (복학원서 워터마크)
- 톤 매핑 단일 문서 특화 쟁점 → 옵션 A 수용, 후속 일반화 권고 기록

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 19, 2026
외부 기여 (postmelee). cherry-pick + 검증 통과 + 시각 판정 통과.
- SVG/WebCanvas/studio overlay 단일 baked PNG 통일
- image crate jpeg feature (WASM JPEG decode)
- test 1484 passed, clippy 0, fmt 0, WASM ok
- 톤 매핑 단일 문서 특화 (옵션 A 수용, 후속 일반화 권고)

검토: mydocs/pr/archives/pr_976_review.md / 보고: pr_976_report.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edwardkim

Copy link
Copy Markdown
Owner

cherry-pick 으로 origin/devel 에 반영 완료 (merge 커밋 9ccc9e2).

검증: cargo test 1484 passed, clippy 0 warnings, fmt 0 violations, WASM 빌드 성공.
시각 판정 통과 (복학원서 워터마크). 옵션 A(수용) 결정.

기여 감사합니다. 검토/보고: mydocs/pr/archives/pr_976_review.md, pr_976_report.md

@edwardkim edwardkim closed this May 19, 2026
edwardkim pushed a commit that referenced this pull request May 19, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 19, 2026
…PaintOp::Image

@postmelee — 이미지 변환(BMP/PCX→PNG) + 워터마크 JPEG→baked PNG 판정이
5+ renderer 별 사본(svg/canvas/web_canvas/skia/paint/json)에 분산되어
있던 것을 LayerBuilder 단계 단일 image_resolver::resolve_image_payload()
진입점으로 통합. 결과를 ResolvedImagePayload 로 패키지하여
PaintOp::Image.resolved: Option<Box<...>> 옵션 필드에 부착 (schema minor
12→13, 하위호환). 모든 renderer 는 resolved payload 소비만 — 재판정 없음.

옵션 A: 본질 커밋 3aeaa5b cherry-pick (작성자 postmelee 보존,
orders/20260520.md --ours 1건 충돌 해소). 검증: cargo test 1307 +
cargo test --test issue_938 3건(overlay/svg/PageLayerTree resolved
watermark contract) + clippy -D + fmt 0 + WASM 4.83MB.

광범위 sweep 10 fixture (BEFORE devel ↔ AFTER): 복학원서(워터마크),
sample16-hwp5/hwp3, hy-001 HWPX/HWP5, exam_kor/math, aift, biz_plan,
test-image — **전부 diff=0** (SVG 출력 100% 동일). 광범위 표면(24파일,
7개 renderer 경로)에도 시각 결과 완전 보존 — feedback_image_renderer_
paths_separate 본질적 해소 + 시각 호환성 100% 모범 사례. 작업지시자
시각 판정 생략 통과 (sweep diff=0 정량 입증).

PR scope 좁힘: z-order replay 일반화는 #1017로 분리 (PR 본문 명시).
@postmelee 후속 #1019 (Task #975 PageBackground fill + RealPic
watermark tone) OPEN 시리즈 연속.
@postmelee postmelee deleted the codex/issue-938-watermark branch June 7, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants