SAP GUI 에서 보고 있는 현재 화면을 그대로 캡처해서 다시 화면 안에 이미지로 띄우는 기능이 필요할 때가 있습니다. 예를 들어 결재 화면을 캡처해 증빙으로 보여주거나, 처리 직전 화면 상태를 이미지로 남길 때입니다. ABAP 에서는 표준 서비스 클래스 CL_GUI_FRONTEND_SERVICES 의 화면 캡처 메소드와 이미지 표시 컨트롤 CL_GUI_PICTURE 를 조합하면 됩니다.
핵심은 데이터 형태를 4번 변환하는 흐름입니다. 화면 캡처는 xstring(바이너리 문자열) 으로 나오는데, 이미지 컨트롤은 URL 을 요구하기 때문에 그 사이를 이어주는 변환 단계가 필요합니다. xstring → 바이너리 테이블 → SAP 내부 URL → 이미지 컨트롤 순서입니다.
이 글에서는 화면 캡처 → MIME 분리 → 바이너리 변환 → URL 생성 → 이미지 표시까지 4단계 흐름과 각 단계에서 쓰는 표준 객체를 정리합니다. 데이터 변환이 핵심이므로 각 함수의 입출력 타입을 명확히 짚습니다.
핵심 — 4단계 데이터 변환 흐름
| 단계 | 사용 객체 | 입력 → 출력 |
|---|---|---|
| 1 | CL_GUI_FRONTEND_SERVICES=>GET_SCREENSHOT |
현재 화면 → MIME 타입 + xstring 이미지 |
| 2 | SCMS_XSTRING_TO_BINARY |
xstring → 바이너리 테이블 + 길이 |
| 3 | DP_CREATE_URL |
바이너리 테이블 → SAP 내부 URL |
| 4 | CL_GUI_PICTURE=>LOAD_PICTURE_FROM_URL |
URL → 컨테이너에 이미지 표시 |
그림으로 정리하면:
현재 화면
│ GET_SCREENSHOT
▼
xstring (이미지) + MIME (예: image/png)
│ SCMS_XSTRING_TO_BINARY
▼
바이너리 테이블 (solix_tab) + 길이
│ DP_CREATE_URL
▼
SAP 내부 URL (cndp_url)
│ CL_GUI_PICTURE->load_picture_from_url
▼
컨테이너(CL_GUI_CUSTOM_CONTAINER) 안에 이미지 표시
1단계 — GET_SCREENSHOT 으로 현재 화면 캡처
CL_GUI_FRONTEND_SERVICES=>GET_SCREENSHOT 은 현재 SAP GUI 화면을 캡처해 MIME 타입 문자열과 이미지 바이너리(xstring) 로 돌려줍니다.
cl_gui_frontend_services=>get_screenshot(
IMPORTING
mime_type_str = DATA(lv_mime) " 예: 'image/png'
image = DATA(lv_image) " xstring
EXCEPTIONS
access_denied = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5 ).
mime_type_str 에 'image/png' 같은 값이, image 에 실제 이미지 바이너리가 담깁니다. 프런트엔드(SAP GUI) 가 있어야 동작하므로 배치 잡에서는 error_no_gui 예외가 발생합니다.
2단계 — MIME 분리 + SCMS_XSTRING_TO_BINARY
URL 을 만들 때 MIME 의 타입/서브타입이 따로 필요하므로 '/' 기준으로 분리하고, xstring 을 바이너리 테이블로 변환합니다.
DATA: lv_type(50),
lv_subtype(50),
lv_len TYPE i,
lt_btab TYPE solix_tab.
* 'image/png' → lv_type='image', lv_subtype='png'
SPLIT lv_mime AT '/' INTO lv_type lv_subtype.
* xstring → 바이너리 테이블
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_image
IMPORTING
output_length = lv_len
TABLES
binary_tab = lt_btab.
SCMS_XSTRING_TO_BINARY 는 xstring 을 solix_tab(1024 바이트 단위 바이너리 라인 테이블) 로 쪼개고, 실제 바이트 길이를 output_length 로 돌려줍니다. 이 길이는 다음 단계 URL 생성에 꼭 필요합니다.
3단계 — DP_CREATE_URL 로 SAP 내부 URL 생성
바이너리 데이터를 SAP 메모리에 올리고, 이미지 컨트롤이 읽을 수 있는 내부 URL 을 발급합니다.
DATA lv_url TYPE cndp_url.
CALL FUNCTION 'DP_CREATE_URL'
EXPORTING
type = lv_type " 'image'
subtype = lv_subtype " 'png'
size = lv_len " 실제 바이트 길이
lifetime = cndp_lifetime_transaction " 트랜잭션 동안 유효
TABLES
data = lt_btab
CHANGING
url = lv_url
EXCEPTIONS
dp_invalid_parameter = 1
dp_error_put_table = 2
dp_error_general = 3
OTHERS = 4.
type·subtype 에 2단계에서 분리한 MIME 값을, size 에 바이트 길이를 넘깁니다. lifetime 을 cndp_lifetime_transaction 으로 주면 트랜잭션이 끝날 때까지 URL 이 살아있어, 화면이 떠 있는 동안 이미지가 유지됩니다.
4단계 — CL_GUI_PICTURE 로 컨테이너에 표시
발급받은 URL 을 이미지 컨트롤에 로드합니다. 이미지 컨트롤은 컨테이너(여기서는 CL_GUI_CUSTOM_CONTAINER) 안에 부착합니다.
DATA: go_conta TYPE REF TO cl_gui_custom_container,
go_image TYPE REF TO cl_gui_picture.
* SE51 Custom Control 'CON1' 과 연결
go_conta = NEW #( container_name = 'CON1' ).
* 이미지 컨트롤을 컨테이너에 부착
go_image = NEW #( parent = go_conta ).
* 표시 모드 — 비율 유지하며 중앙 맞춤
go_image->set_display_mode( cl_gui_picture=>display_mode_fit_center ).
* URL 로드
go_image->load_picture_from_url( lv_url ).
load_picture_from_url 에 3단계 URL 을 넘기면 캡처한 화면이 컨테이너에 그려집니다. 컨테이너 없이 전체 화면에 바로 띄우려면 parent = cl_gui_container=>default_screen 을 쓰는 방법도 있습니다.
display_mode 옵션
set_display_mode 로 이미지가 컨테이너 안에서 어떻게 배치될지 결정합니다.
| 상수 | 값 | 동작 |
|---|---|---|
DISPLAY_MODE_NORMAL |
0 | 원본 크기 그대로 (좌상단 기준) |
DISPLAY_MODE_STRETCH |
1 | 컨테이너에 꽉 차게 늘림 (비율 무시) |
DISPLAY_MODE_FIT |
2 | 비율 유지하며 맞춤 (좌상단 기준) |
DISPLAY_MODE_NORMAL_CENTER |
3 | 원본 크기 + 중앙 정렬 |
DISPLAY_MODE_FIT_CENTER |
4 | 비율 유지 + 중앙 맞춤 (가장 무난) |
화면 캡처처럼 비율이 중요한 이미지는 DISPLAY_MODE_FIT_CENTER(비율 유지 + 중앙) 가 가장 자연스럽습니다.
자주 빠뜨리는 함정
캡처 시점 — 어느 화면이 찍히는가
GET_SCREENSHOT 은 "호출되는 순간 떠 있는 화면" 을 캡처합니다. 셀렉션 스크린에서 실행하면 셀렉션 스크린이 찍히고, 특정 화면을 캡처하려면 그 화면이 활성일 때 호출해야 합니다.
size 누락 — 이미지 깨짐
DP_CREATE_URL 의 size 에 2단계의 output_length 를 안 넘기면, 바이너리 테이블의 마지막 라인 패딩까지 포함되어 이미지가 깨지거나 끝부분이 잘립니다. 실제 바이트 길이를 반드시 전달하세요.
MIME 분리 누락
DP_CREATE_URL 은 type·subtype 을 따로 받습니다. 'image/png' 전체를 그대로 넘기면 안 되고 SPLIT 으로 나눠야 합니다.
컨테이너 생성 시점 — PBO 에서
CL_GUI_CUSTOM_CONTAINER 는 Custom Control 이 있는 화면이 활성일 때 생성해야 합니다. START-OF-SELECTION 에서 만들면 아직 화면 100 이 안 떠서 바인딩이 안 됩니다. 캡처·변환·URL 생성은 START-OF-SELECTION 에서, 컨테이너·이미지 생성은 PBO 에서 분리하는 게 안전합니다.
lifetime 너무 짧음
DP_CREATE_URL 의 lifetime 을 너무 짧게 주면 화면이 떠 있는 동안 URL 이 만료되어 이미지가 사라질 수 있습니다. 화면 표시용은 cndp_lifetime_transaction 이 무난합니다.
전체 코드 — 복사용 통합본
아래 통합본은 SE38 에 그대로 붙여 활성화 가능. SE51 에서 Screen 100 에 Custom Control 'CON1' 을 그린 뒤, Flow Logic 에 status_0100 · create_pic · user_command_0100 모듈 연결 + GUI Status 'S100' 등록만 추가하면 완성. 캡처·변환은 START-OF-SELECTION, 표시는 PBO 로 분리했습니다.
*&---------------------------------------------------------------------*
*& Report ZRXX_SCREENSHOT_PIC (예시)
*&---------------------------------------------------------------------*
*& 현재 화면 캡처 → 컨테이너에 이미지로 표시
*&---------------------------------------------------------------------*
REPORT zrxx_screenshot_pic.
* 캡처 결과 + 변환용 (PBO 에서 쓰므로 전역)
DATA: gv_mime TYPE string,
gv_image TYPE xstring,
gv_url TYPE cndp_url,
gv_type(50),
gv_subtype(50),
gv_len TYPE i,
gt_btab TYPE solix_tab.
DATA: go_conta TYPE REF TO cl_gui_custom_container,
go_image TYPE REF TO cl_gui_picture,
ok_code TYPE sy-ucomm.
START-OF-SELECTION.
* 1) 현재 화면 캡처
cl_gui_frontend_services=>get_screenshot(
IMPORTING
mime_type_str = gv_mime
image = gv_image
EXCEPTIONS
access_denied = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
MESSAGE '화면 캡처 실패' TYPE 'I'.
RETURN.
ENDIF.
* 2) MIME 분리 + xstring → 바이너리
SPLIT gv_mime AT '/' INTO gv_type gv_subtype.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = gv_image
IMPORTING
output_length = gv_len
TABLES
binary_tab = gt_btab.
* 3) SAP 내부 URL 생성
CALL FUNCTION 'DP_CREATE_URL'
EXPORTING
type = gv_type
subtype = gv_subtype
size = gv_len
lifetime = cndp_lifetime_transaction
TABLES
data = gt_btab
CHANGING
url = gv_url
EXCEPTIONS
dp_invalid_parameter = 1
dp_error_put_table = 2
dp_error_general = 3
OTHERS = 4.
CALL SCREEN 100.
* PBO — GUI Status
MODULE status_0100 OUTPUT.
SET PF-STATUS 'S100'.
SET TITLEBAR 'T100'.
ENDMODULE.
* PBO — 컨테이너 + 이미지 표시 (★ 4단계)
MODULE create_pic OUTPUT.
IF go_conta IS NOT BOUND.
go_conta = NEW #( container_name = 'CON1' ).
go_image = NEW #( parent = go_conta ).
go_image->set_display_mode( cl_gui_picture=>display_mode_fit_center ).
go_image->load_picture_from_url( gv_url ).
ENDIF.
ENDMODULE.
* PAI
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'BACK' OR 'CANC' OR 'EXIT'.
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE.

요약
| 단계 | 객체 | 변환 |
|---|---|---|
| 1 | GET_SCREENSHOT |
화면 → MIME + xstring |
| 2 | SPLIT + SCMS_XSTRING_TO_BINARY |
MIME 분리 + xstring → 바이너리 |
| 3 | DP_CREATE_URL |
바이너리 → SAP 내부 URL |
| 4 | CL_GUI_PICTURE |
URL → 컨테이너에 표시 (load_picture_from_url) |
현재 화면을 캡처해 다시 띄우는 작업의 본질은 "캡처는 xstring, 표시는 URL — 그 사이를 바이너리 변환으로 잇기" 한 줄. GET_SCREENSHOT 으로 찍고, SCMS_XSTRING_TO_BINARY 로 쪼개고, DP_CREATE_URL 로 URL 을 발급해 CL_GUI_PICTURE 에 로드. 같은 흐름은 화면 캡처뿐 아니라 서버에 저장된 임의의 이미지(xstring) 를 화면에 띄울 때도 그대로 쓸 수 있습니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다. CL_GUI_FRONTEND_SERVICES=>GET_SCREENSHOT 와 CL_GUI_PICTURE 의 load_picture_from_url · display_mode 상수(FIT_CENTER=4 등) 는 NetWeaver 표준 정의(ECC 6.0 / S/4HANA on-premise 기준) 입니다. GET_SCREENSHOT 은 SAP GUI 프런트엔드가 있어야 동작하므로 배치/백그라운드에서는 사용할 수 없습니다. 적용 환경 버전에 따라 일부 차이가 있을 수 있으니 실제 적용 시 SE24 의 클래스 정의를 확인하시기 바랍니다.