이 영역 캡처는 드래그를 끝낸 순간의 화면을 새로 찍지 않는다. 선택창을 열기 전에 보이는 데스크톱 픽셀을 얻고, 그 화면을 배경으로 영역을 고르게 한다. 저장하는 것도 선택창이 덧그려진 화면이 아니라 처음 얻은 픽셀의 일부다.
교체 요청의 대상은 기존 자동화 도구의 Python 캡처를 Rust로 바꾸는 일이었다. 요청·완료 기록과 소스·보존된 검증 결과를 대조할 때, 선택 화면의 픽셀이 그대로 저장되는지부터 확인했다.
화면을 먼저 얻고 그 위에서 고르게 한다
확인한 실행 순서는 화면 픽셀 얻기, 선택창 표시, 선택 영역 자르기, PNG 저장이다. 선택창은 이미 얻은 픽셀 버퍼를 그려 보여준다. 마우스를 놓으면 그 버퍼의 행과 열을 잘라 결과를 만든다. 화면 위에 그린 안내 문구와 선택 테두리를 다시 찍지 않는다.
사용자가 영역을 고르는 동안 뒤쪽 동영상이나 시계가 바뀌어도 결과는 처음 얻은 버퍼를 따른다. 마우스를 놓은 순간의 화면을 새로 담지는 않는다. 움직이는 장면의 최신 상태가 필요하면 원하는 장면이 보일 때 캡처를 다시 시작해야 한다.
선택창을 먼저 띄우고 캡처하면 안내창을 결과에서 빼는 처리가 필요하다. 이 구현은 선택창을 띄우기 전의 버퍼를 재사용하므로 그 처리를 피한다. 코드 순서로 확인한 설계상의 차이이며 속도 개선을 측정한 결과는 아니다.
코드와 구현 살펴보기
설명용 순서도 · 실행 코드 아님
Host hidden
-> acquire visible desktop pixels
-> show selection overlay using that buffer
selected -> crop original buffer -> encode temporary PNG
-> persist without replacing an existing file
-> return area + file receipt
cancelled -> return no selected region; no final PNG드래그 방향을 정리한 뒤 화면 원점을 더한다
선택 사각형은 시작점과 끝점 중 작은 값을 왼쪽과 위쪽으로 잡고, 두 점의 차이의 절댓값을 너비와 높이로 쓴다. 오른쪽 아래에서 왼쪽 위로 끌어도 사각형을 만들 수 있는 이유다. 여기서는 너비와 높이가 각각 8픽셀 이상일 때만 선택 결과로 받는다.
선택창 안의 좌표에는 가상 화면의 원점을 더해 실제 화면 좌표로 돌려준다. 전체 화면 원점이 음수일 수 있다는 계산을 포함한다. 다만 음수 원점을 계산할 수 있다는 것과 실제 여러 모니터의 배율·배치를 시험했다는 것은 다르다.
안내문은 좌표 단위를 실제 화면 픽셀로 명시한다. 소스도 DPI 인식 컨텍스트를 설정하고 가상 화면 크기를 읽는다. 기존 기록의 실제 저장 환경은 150% 확대율의 2560×1600 화면이다. 이 한 환경의 결과를 모든 배율과 다중 모니터의 검증으로 확대하지 않았다.
취소 콜백의 대체 이미지는 저장 성공이 아니다
ESC, 창 닫기, 선택 시간 초과는 영역 저장 완료와 다른 결과다. 선택 결과가 없으면 네이티브 쪽은 취소 또는 시간 초과 오류를 반환하고 최종 PNG 저장 단계로 넘어가지 않는다. 너무 작은 드래그도 유효한 영역이 되지 않는다.
기존 Python 화면과 Rust 실행 파일은 어댑터로 연결한다. 선택을 시작할 때 기존 화면을 숨기고, 결과가 돌아오면 임시 자료를 정리한 뒤 원래 화면을 다시 보여준다. 취소 콜백에도 작은 대체 이미지는 전달되지만 영역은 없다. 받는 쪽은 이미지 객체의 존재가 아니라 선택 영역의 유무도 함께 확인해야 한다.
정상 응답에서는 JSON의 영역 너비·높이와 실제 PNG 크기를 대조한 뒤 기존 이미지 처리 코드에 넘긴다. 파일이 있다는 확인에 더해, 선택한 영역과 저장한 크기가 맞는지 확인하는 단계다.
기존 파일은 마지막 저장 단계에서도 지킨다
저장 시작 시 목적지 파일의 존재와 부모 폴더를 확인한다. 실제 PNG는 같은 폴더에 만든 임시 파일에 쓰고, 저장을 확인한 뒤 기존 파일을 대체하지 않는 방식으로 최종 이름에 남긴다. 처음 확인 이후 다른 작업이 같은 이름을 만들 수도 있으므로 마지막 단계에서도 덮어쓰기를 막는다.
완료 결과에는 파일 경로·바이트 수·SHA-256과 영역이 포함된다. 이 영수증은 어떤 파일이 만들어졌는지 대조할 자료다. 화면의 내용이 올바른 업무 자료였는지, 민감 정보가 없는지까지 증명하지 않는다. 임시 파일 정리와 기존 이미지 보존도 각각 확인할 항목이다.
이 구조를 적용할 때에는 취소를 반복한 뒤 최종 파일이 생기지 않는지, 이미 있는 파일이 보존되는지, 역방향 선택 결과의 실제 크기가 맞는지를 따로 살펴볼 수 있다. 이는 적용 시 확인할 항목이며 이 글을 쓰며 원래 프로그램에 새로 실행한 시험은 아니다.
캡처는 Rust, 기존 화면과 인식은 Python
이번 교체의 대상은 화면 픽셀 취득과 영역 선택, PNG 생성이다. 기존 UI와 OpenCV 인식·자동화 동작은 Python을 유지하고, Pillow는 결과 PNG를 읽는다. 캡처 실행 파일을 바꿨다고 전체 프로그램이 Rust가 됐다고 쓰지 않았다.
과거 네이티브 검증 JSON에는 화면 크기, 합성 색상 일치, 기존 출력 보존, 잘못된 영역의 출력 없음, 시간 초과와 임시 파일 정리 항목이 기록돼 있다. 별도의 패키지 검증에는 역방향 드래그와 저장한 이미지 크기·파일 수가 남아 있다. 이번 집필에서는 그 기록과 소스를 읽었고 캡처나 원제품 시험을 재실행하지 않았다.
안내문은 음수 원점의 단위 검사와 실제 다중 모니터 검증을 구분하며, 공통 코드 검수 응답은 미확인으로 남긴다. 보이는 데스크톱 픽셀을 다루는 엔진이므로 가려진 창의 원래 내용과 Windows 보안 데스크톱을 얻는 기능으로 소개할 수 없다. 보호 콘텐츠와 HDR 화면도 별도 확인이 필요하다.
캡처를 비교 자료로 쓸 때에는 이 저장 순서에 더해 페이지·슬라이드·스크롤·글꼴 준비 상태도 맞춰야 한다. 먼저 찍은 화면에서 정확한 영역을 골랐다는 사실과 비교할 두 장이 같은 상태라는 사실은 각각 확인한다.