프로그래밍 노트

[델파이] bmp의 지정한 색을 투명하게 그리기 2 본문

델파이

[델파이] bmp의 지정한 색을 투명하게 그리기 2

떡잎 2010. 1. 15. 15:20

bmp의 지정한 색을 투명하게 그리는 소스


procedure TForm1.DrawOpaque0Bmp(Cnvs: TCanvas; bmpSource: TBitmap; x, y: integer;
  clTransparent: TColor);
var
  width, height : integer;
  clPrevColor: TColor;
  tpBmpSize : TPOINT;
  bmpInfo : BITMAP;
  hSourceBmp : HBitmap;
  hdcTarget,  hdcSource : HDC;
  bmAndMask, bmAndObject, bmAndMem, bmWork    : HBITMAP;
  bmMaskOld, bmObjectOld, bmMemOld, bmWorkOld : HBITMAP;
  hdcMask,   hdcObject,   hdcMem,   hdcWork   : HDC;

begin
  hdcTarget  := Cnvs.Handle;
  hSourceBmp := bmpSource.Handle;

  // 메모리 디바이스 컨텍스트 만들기
  //    Memory Device Context(DC)
  //        메모리의 논리적 디바이스
  //        디바이스의 입구를 가르키는 핸들
  //        그림을 그리기 위한 Bit열의 메모리
  //        그림을 그리기 위한 캔버스
  hdcSource := CreateCompatibleDC(hdcTarget);
  // selects an object into the specified device context (DC)

  // 지정한 DC에 지정한 메모리 오브젝트를 붙임
  SelectObject(hdcSource, hSourceBmp);

  // 지정한 Bitmap 메모리 오브젝트의 정보 가져오기
  GetObject(hSourceBmp, sizeof(BITMAP), @bmpInfo);
  tpBmpSize.x := bmpInfo.bmWidth;   width  := tpBmpSize.x;
  tpBmpSize.y := bmpInfo.bmHeight;  height := tpBmpSize.y;

  // DC에 설정한 좌표를 설정
  DPtoLP(hdcSource, tpBmpSize, 1);

  // 작업용 DC 만들기
  hdcMask   := CreateCompatibleDC(hdcTarget);
  hdcObject := CreateCompatibleDC(hdcTarget);
  hdcMem    := CreateCompatibleDC(hdcTarget);
  hdcWork   := CreateCompatibleDC(hdcTarget);

  // 흑백 Bitmap 만들기
  bmAndMask   := CreateBitmap(width, height, 1, 1, nil);
  bmAndObject := CreateBitmap(width, height, 1, 1, nil);

  // 지정 DC 호환 Bitmap 만들기
  bmAndMem    := CreateCompatibleBitmap(hdcTarget, width, height);
  bmWork      := CreateCompatibleBitmap(hdcTarget, width, height);

  // 지정한 DC에 지정한 메모리 오브젝트를 붙임
  //    DC에 그림 붙여넣기
  bmMaskOld   := SelectObject(hdcMask,   bmAndMask);
  bmObjectOld := SelectObject(hdcObject, bmAndObject);
  bmMemOld    := SelectObject(hdcMem,    bmAndMem);
  bmWorkOld   := SelectObject(hdcWork,   bmWork);

  // Target DC에 Source DC의 맵핑 모드 설정
  SetMapMode(hdcSource, GetMapMode(hdcTarget));

  // 사각형에 Bit Block 전송
  //    (SRCCOPY    : Source를 Target에 복사)
  //    (NOTSRCCOPY : 색을 반전시킨 Source를 Target에 복사)
  //    (SRCAND     : Source와 Target의 색을 논리 AND 연산)
  //    (SRCPAINT   : Source와 Target의 색을 논리 OR 연산)

  BitBlt(hdcWork,   0, 0, width, height, hdcSource, 0, 0, SRCCOPY);
  clPrevColor := SetBkColor(hdcSource, clTransparent);  // 지정한 DC의 배경색을 설정
  BitBlt(hdcObject, 0, 0, width, height, hdcSource, 0, 0, SRCCOPY);
  SetBkColor(hdcSource, clPrevColor); // 지정한 DC의 배경색을 기존 색상으로 설정
  BitBlt(hdcMask,   0, 0, width, height, hdcObject, 0, 0, NOTSRCCOPY);
  BitBlt(hdcMem,    0, 0, width, height, hdcTarget, x, y, SRCCOPY);
  BitBlt(hdcMem,    0, 0, width, height, hdcObject, 0, 0, SRCAND);
  BitBlt(hdcSource, 0, 0, width, height, hdcMask,   0, 0, SRCAND);
  BitBlt(hdcMem,    0, 0, width, height, hdcSource, 0, 0, SRCPAINT);
  BitBlt(hdcTarget, x, y, width, height, hdcMem,    0, 0, SRCCOPY);
  BitBlt(hdcSource, 0, 0, width, height, hdcWork,   0, 0, SRCCOPY);

  // 만들었던 메모리 Bitmap 데이터 삭제
  DeleteObject(SelectObject(hdcMask, bmMaskOld));
  DeleteObject(SelectObject(hdcObject, bmObjectOld));
  DeleteObject(SelectObject(hdcMem, bmMemOld));
  DeleteObject(SelectObject(hdcWork, bmWorkOld));

  // 만들었던 메모리 DC 삭제
  DeleteDC(hdcMem);
  DeleteDC(hdcMask);
  DeleteDC(hdcObject);
  DeleteDC(hdcWork);
  DeleteDC(hdcSource);
end;

Comments