Repository navigation
feat(crop): add a perspective mode that straightens a tilted picture - #764
Merged
Merged
Conversation
KnifeLemon
requested changes
Oct 29, 2026
KnifeLemon
left a comment
Owner
There was a problem hiding this comment.
@SeoJCalive 고마워요! 원근 변환 계산, 픽셀 매핑, EXIF 회전, 알파, PDF 처리, 여러 장 넘길 때의 흐름 모두 맞게 동작해요. 기존 사각형 자르기도 그대로예요. 하나만 고치면 머지할게요.
고쳐 주세요
- 모서리가 그림 밖으로 나가는 이동은 버리지 말고 가장자리에 붙여 주세요. (
CropMath.MoveCorner/NudgeCorner)- 마우스: 모서리를 그림 귀퉁이 쪽으로 빠르게 끌면, 밖으로 나간 첫 이벤트가 통째로 무시돼요. 그래서 모서리가 가장자리 몇 픽셀 앞에서 멈춰요. 문서가 사진을 꽉 채운 경우, 저장된 그림 한쪽에 배경이 얇게 남아요.
- 키보드: 가장자리에서 3px 떨어진 모서리에서 Shift+← (−10)를 누르면 아무 일도 안 일어나요. 사각형 틀의
CropMath.Nudge는 가장자리까지 붙여요. - 방법: 목표 위치를 먼저 [0, 1]로 자른 다음 볼록 검사를 하고, 꼬이거나 오목한 모양만 거부하면 돼요.
- 테스트: 지금 "밖으로" 경우는 모서리가 이미 x=0에서 시작해서 이 상황이 빠져 있어요. 가장자리 근처에서 시작하는 경우를 넣어 주세요.
함께 고치면 좋은 것 (막지는 않아요)
- 한국어:
crop.perspective_pdf의 "그림", "PDF 쪽"은 ko.json의 다른 문구처럼 "이미지", "PDF 페이지"로 맞춰 주세요.perspective_tip의 "사진"과도 통일해 주세요.- 버튼 이름 "원근"만으로는 뜻이 약해요. 일본어 "遠近補正"처럼 "원근 보정"이 좋겠어요.
- 전역
Button.tool:disabled스타일(불투명도 0.45)이 기존 도구 버튼에도 적용돼요. 예를 들어 비동기 명령이 도는 동안 건너뛰기 버튼이 흐려져요. 원근 토글에만 걸어 주세요. - 사각형 그대로 저장할 때: 모서리를 안 움직인 사각형도 매번 Distort로 다시 샘플링해서 조금 흐려지고 느려요. 축에 맞는 직사각형이면 기존
Crop경로로 보내 주세요. - 파일 머리 주석:
CropMath.cs(이제CropQuad도 있음),CropCanvas.cs, 두 테스트 파일의 머리 주석을 새 내용에 맞게 고쳐 주세요.
창 최소 너비 680 → 720은 괜찮아요.
CI는 "Test UI on its own" 단계에서 취소돼서 결과가 없어요. 다음 push 때 다시 돌 거예요.
Collaborator
Author
|
@KnifeLemon 리뷰 감사해요! 지금 반영하고 있어요.
검증까지 마치면 올리고 다시 알려 드릴게요. |
An icon-only perspective toggle next to the ratio button lets each of the four corners move on its own. Saving straightens the chosen quad into a rectangle whose width is the longer of the top and bottom edges and whose height is the longer of the left and right edges. Output path, format, quality and date rules are the same as the rectangle crop. - Corners cannot be moved into a crossing, concave or flat shape, or outside the picture; a refused move leaves the corner where it was. - Tab picks a corner, arrow keys move it by one pixel (Shift: ten), and each corner has a localized screen-reader name. - The ratio dial and custom ratio are off while the mode is on. Each next picture starts with the corners on its own frame and the mode stays on. PDFs keep the rectangle crop and the toggle explains why. - A corner follows the pointer's travel, so grabbing it off-centre doesn't make it jump. A drag ends when the mode or the picture changes under it, for the rectangle frame too. - The crop window's minimum width goes from 680 to 720 so the toolbar with the new toggle, a custom ratio and several files still fits. - Test pictures are drawn in code. Closes #699
… rectangles unresampled - A corner dragged or nudged past the picture now stops on its edge instead of the move being dropped; only twisted, concave or collinear shapes are refused. - Corners still on a whole-pixel axis-aligned rectangle save through the plain crop, without a perspective resample. - The disabled fade applies only to the ratio and perspective buttons, not to every toolbar button. - Korean: "원근 보정", "이미지", "PDF 페이지". - File header comments cover the perspective mode.
SeoJCalive
force-pushed
the
feature/perspective-crop
branch
from
October 29, 2026 13:58
9f46201 to
44c6830
Compare
Collaborator
Author
|
@KnifeLemon 꼼꼼히 봐 주셔서 감사해요! 말씀하신 다섯 가지 모두 반영했어요.
1번을 고치기 전과 후를 같은 조작으로 찍었어요. 이미지를 꽉 채운 문서에서 가장자리 60px 안쪽의 왼쪽 위 모서리를 귀퉁이 밖으로 한 번에 끌었어요.
PR 본문의 모서리 제한·저장 설명도 바뀐 동작에 맞게 고쳤어요. |
KnifeLemon
approved these changes
Oct 29, 2026
KnifeLemon
left a comment
Owner
There was a problem hiding this comment.
@SeoJCalive 다섯 가지 모두 확인했어요. 고마워요!
- 모서리: 목표 위치를 먼저 [0, 1]로 자르고 나서 검사해요. 키보드 이동도
MoveCorner를 거치니까 똑같이 가장자리에 붙어요. 전후 스크린샷도 잘 봤어요. - 사각형 그대로 저장: 정수 픽셀에 맞는 직사각형은 일반
Crop경로로 가고, 픽셀까지 같은지 시험도 있어요. - 흐림 스타일: 비율 버튼과 원근 토글에만 걸려요.
- 한국어와 머리 주석: 모두 맞췄어요.
머지할게요. #699도 함께 닫혀요.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.






What does this change?
Adds a perspective mode to the crop window. With the perspective toggle right next to the ratio button turned on, each of the four corners moves on its own, and saving straightens the chosen quad into a flat rectangle. It's for photos of documents, receipts or screens taken at an angle, the way a document scanner app works. Closes #699
Choices I made
Type of change
How was it tested?
dotnet format --verify-no-changesdotnet testTried it in the app (what you converted or clicked, and on which OS): in the crop window on headless Linux (X11): the toggle, dragging corners, refused moves, keyboard moves and the saved result.
Changed-area tests (crop window, crop service, crop math, pixelate window, localization): 318 tests, all passed.
Full App suite: 1,580 of 1,590 passed, 9 skipped, 1 failed. The failing
RenderTests.Engines_page_shows_versions_descriptions_and_download_speedalso fails without this PR (on11769a89) in the same environment. Core: all 728 passed.Build warnings: the same as the base commit, and
dotnet format --verify-no-changespasses.Do the new tests guard the feature: I made 33 mutations, each undoing one part of the change (the convexity check, stopping a corner on the edge, saving a plain rectangle without resampling, which buttons fade when disabled, moving by pointer travel, state changes during a drag, output size, key moves, screen-reader names, PDF handling and so on), and checked that a test fails for every one.
Saved result: straightening the code-drawn tilted four-colour rectangle gives a 573 × 391 px file whose quadrant centres are exactly red, green, yellow and blue.
How to check it yourself
_croppedfile appears in the same folder. Dragging a corner past another one doesn't move it, and dragging it off the picture stops it on the edge.dotnet test tests/Filee.App.Tests -c Release --filter "FullyQualifiedName~CropOverlayTests|FullyQualifiedName~CropServiceTests|FullyQualifiedName~CropMathTests".CropServiceTests.A_perspective_crop_straightens_a_tilted_picturechecks the saved file's size and quadrant colours, and the run writes the screens shown below totests/Filee.App.Tests/bin/Release/net10.0/screenshots/crop-perspective-*.png.Screenshots (UI changes)
A code-drawn tilted four-colour rectangle, straightened and saved in perspective mode.
The crop window with the same picture. Before, the rectangle frame takes the grey around it too; after, the four corners sit on the picture's corners.
Dark theme
Several pictures: on the second picture the mode is still on, the corners start on its edges, and the corner picked with the keyboard has a ring
Checklist
src/Filee.App/Assets/i18n/*.jsonfilesTHIRD-PARTY-NOTICES.md(none)Follow-up