델파이 VCL의 TGraphic, TPicture, TImage은 무엇이며, 그래픽 파일 포맷은 어떻게 변환하는 것인가요?
출처 : http://www.awaresystems.be/techtalks/003_graphic_picture_image.html

역자주: 저역시도 항상 헷깔리는 부분입니다. 예전에 확실히 알아두었는데 요즘엔 또 헷깔리더군요. 예전에 누군가 잘 정리해둔 문서가 있었는데 지금 찾아보려니 없었습니다. 그래서 인터넷 검색해 보니 찾아진 문서가 이것입니다. 짧은 영어지만 번역해 보았습니다. (많이 의역했으므로 이해바랍니다.)

TGraphic, TPicture, TImage에 대해서는 많이들 혼란스러워 한다. VCL에서 TGraphic을 둬서 디자인을 한 의도는 도통 이해하기 어렵고, TBitmap, TImage 역시 상당히 혼란스럽다. (문서화까지 제대로 되어있지 않다.)
그럼에도 불구하고 상당히 좋은 디자인이긴 하다.

간단히 말해서 (완전히 정확한 내용은 아니다)

1. TGraphic은 그래픽 데이터를 관리하고, 드로잉 표면(drawing surface) (TCanvas와 윈도우즈 DC)에 그리는 기능을 한다.
  1.1. TGraphic을 상속받은 객체 (TJpegImage, TBitmap 등)은 해당 파일 포맷을 읽고 쓰는 기능이 추가된 것이다. 그래서 TJpegImage는 그래픽 데이터를 관리하고 그릴 수 있으며, 또한 JPEG 파일로부터 그래픽 테이터를 읽고 쓸 수 있다.
  1.2. TBitmap은 위에 말한 다양한 기능들을 다루기 위한 객체이며, 또한 윈도우 레벨의 그래픽 오브젝트이다. (여기서 그래픽 오브젝트는 윈도우즈 운영체제에서 말하는 "그래픽 오브젝트"를 말하는 것임) 그래서 특정 파일 포맷과는 무관하게 임시 버퍼 등으로 사용할 수 있는 객체이다. (순수하게 비트맵이라는 용어 자체가 비트의 배열을 가지고 있다는 뜻이므로)
  1.3. TPicture는 TGraphic을 내부적으로 사용한다. (TBitmap, TJpegImage와 같은 TGraphic을 상속받는 애들을 사용한다.) 그래서 TPicture의 LoadFromFile 메서드에서는 파일 확장자에 따라서 해당하는 파일 포맷을 위한 TGraphic 객체 (TGraphic을 상속받은 객체)를 생성해서 실제 파일을 로드하는 작업을 위임시킨다.
2. TImage는 TPicture 객체를 가지고 있고 그것을 관리한다. TImage가 TPicture를 대체하려고 있는 것은 아니고, UI 등에 그리는 기능을 보완하기 위해 있는 것이다. 그러므로 그래픽 데이터를 다루기 위해서 Visible 속성이 False인 TImage를 사용하는 것은 옳지 않다.

(위의 내용이 다 완전히 맞는 것은 아니다. TGraphic 객체가 그래픽 데이터를 관리하고 그리는 방법을 실제로 아는 것은 아니다. 그 기능들은 TGraphic을 상속받은 애들이 한다. 이러한 점은 좋은 설계라고 할 수 있다. TGraphic를 상속한 객체를 만드므로써 여러가지 상황에 대처할 수 있기 때문이다. 예를 들면, 매우 큰 이미지를 다루어야 한다거나 할 경우 TGraphic를 상속해서 해당 기능에 최적화된 객체를 구현하면 되기 때문이다.)

이러한 TGrahpic의 객체지향적인 설계를 활용할 수 있는 가장 흔한 예는 그래픽 파일 포맷 간의 변환을 들 수 있다. JPEG 파일을 BMP 파일로 변환한다고 생각해봐라. 그러기 위해서는 JPEG 파일에서 래스터 이미지 데이터를 읽어들이고, BMP 파일로 래스터 이미지 데이터를 쓰는 작업을 해 주어야 한다. 델파이에서는 이 작업을 TJpegImage 객체와 TBitmap 객체를 이용하여 손쉽게 할 수 있다.

procedure ConvertJpegFileToBitmapFile(const SourceFilename, DestinationFilename: String);
var
  jpeg: TJpegImage;
  bmp: TBitmap;
begin
  jpeg := TJpegImage.Create;
  try
    jpeg.LoadFromFile(SourceFilename);
    bmp := TBitmap.Create;
    try
      bmp.Assign(jpeg);
      bmp.SaveToFile(DestinationFilename);
    finally
      bmp.Free;
    end;
  finally
    jpeg.Free;
  end;
end; 

(역자주 : Assign 함수를 호출함으로서 우리가 원하는 목적을 쉽게 이룰 수 있다. 다시 말해서 TGrpahic를 상속받은 애들 사이에는 Assign 함수를 호출함으로서 그래픽 포맷 변환을 쉽게 할 수 있다.)

위에서 보았듯이 Assign 함수로 해당 작업을 수행했다. Assing 함수는 공식적으로는 두 객체간에 그래픽 데이터는 복사한다고 되어있지만, TJpegImage, TBitmap 등의 그래픽 객체는 실제로 그러한 메모리 복사 작업을 하지는 않는다. 그래픽 데이터를 담고 있는 객체를 공유하며 단지 사용 카운터 (usage counter)를 증가시킬 뿐이다.