Revision 1 of 1, by Trev on 2-9-2020. The page as it is now.
Developing with Graphics/ko
ì�´ 페ì�´ì§€ëŠ” 비트맵과 다른 그래픽들 다루는 íŠœí† ë¦¬ì–¼ì�˜ 시작ì�´ ë� 것ì�´ë‹¤. 나는 프로그래머가 아니지만, ìž�ì‹ ì�˜ 경험ì�„ 나눌 수 있는 사람ì�€ 누구나 다 초대한다! 다ì�Œ 섹션ì—� ë§�í�¬ë¥¼ ì¶”ê°€í•˜ê³ íŽ˜ì�´ì§€ë¥¼ ë�”í•˜ê³ ìž�ì‹ ì�˜ WiKi 문서를 만들기만 하면 ë�œë‹¤.
ì�´ 페ì�´ì§€ì—�ì„ ì�¼ë°˜ì �ì�¸ ì •ë³´ë¥¼ 줄 것ì�´ë‹¤.
��브러리
그래픽 ë�¼ì�´ë¸ŒëŸ¬ë¦¬ - ì�´ê³³ì—�서는 개발ì—� ì‚¬ìš©í• ìˆ˜ 있는 주요한 그래픽 ë�¼ì�´ë¸ŒëŸ¬ë¦¬ 들ì�„ ë³¼ 수 있ì�„ 것ì�´ë‹¤.
다른 그래픽 문서
2D 그리기
- ZenGL - OpenGL� �용한 �로스 플랫� 게임 개발 ��브러리
- BGRABitmap - 픽셀 등ì�„ ì§�ì ‘ ì ‘ê·¼í•˜ì—¬ shapeê³¼ 비트맵ì�„ 투병하게 그림
- LazRGBGraphics - 메모리 �미지 프로세싱과 팩셀 조작(스캔 �� 처럼)� 쉽게 하기 위한 패키지.
- fpvectorial - 벡터ì�´ë¯¸ì§€ì�˜ ì�½ê¸°, ìˆ˜ì • 기ë¡�ì�„ ì§€ì›�
- �블 그래디언트 - 'double gradient' & 'n gradient' 비트맵� 쉽게 그림
- 그래디언트필터 - TGradientFiller는 ë�¼ìž�루스ì—�서 사용지 그래디언트를 만드는 ìµœì„ ì�˜ 방법ì�´ë‹¤.
- PascalMagick - ImageMagickê³¼ ì�¸í„°íŽ˜ì�´ìŠ¤í• ìˆ˜ 있는 API를 사용하기 쉽게 한다. 멀티 플랫í�¼ì�˜ ìž�ìœ ì†Œí”„íŠ¸ì›¨ì–´ 수트로 비트맵 ì�´ë¯¸ì§€ë¥¼ ìƒ�성, íŽ¸ì§‘í•˜ê³ êµ¬ì„±í• ìˆ˜ 있다.
- 샘플 그래픽 - ��루스와 드로잉 툴� �용한 그래픽 갤러리
- ë¹ ë¥¸ ì§�ì ‘ 픽셀 ì ‘ê·¼ - ì§�ì � 비트맵 픽셀 ì ‘ê·¼ì�„ 위한 ë©”ì�˜ë“œë“¤ì�˜ 비êµ�
- AggPas - AggPas 는 Anti-Grain Geometry ë�¼ì�´ë¸ŒëŸ¬ë¦¬ì�˜ 오브ì �트 파스칼 변환물로서 안티 알리아싱ë�œ 드로잉과 ì •í™•í•œ 서브 픽셀ì�˜ ì •í™•ì„±ì—�있어서 ë¹ ë¥´ê³ ê°•ë ¥í•œ 기능ì�„ ì œê³µí•œë‹¤. AggPas를 메모리ìƒ�ì—�서 몇몇 벡터 ë�°ì�´í„°ë¡œë¶€í„°í”½ì…€ ì�´ë¯¸ì§€ë¥¼ 만드는 ë Œë�”ë§� 엔진으로 ì‚¬ìš©í• ìˆ˜ê°€ 있다.
3D 그리기
ì± íŠ¸
- TAChart - ë�¼ìž�루스ì�˜ ì± íŒ… ì»´í�¬ë„ŒíЏ
- PlotPanel - ì• ë‹ˆë§¤ì�´íЏ 그래프를 위한 플롯과 ì± íŒ… ì»´í�¬ë„ŒíЏ.
- Perlin Noise - LCL 어플리케�션�서 Perlin Noise를 사용하는 것� 대한 문서.
LCL� 그래픽 모�� 대한 소개
The LCL provides two kinds of drawing class: Native classes and non-native classes. Native graphics classes are the most traditional way of drawing graphics in the LCL and are also the most important one, while the non-native classes are complementary, but also very important. The native classes are mostly located in the unit Graphics of the LCL and are the well known classes: TBitmap, TCanvas, TFont, TBrush, TPen, TPortableNetworkGraphic, etc.
TCanvas is a class capable of executing drawings. It cannot exist alone and must either be attached to something visible (or at least which may possibly be visible), such as a visual control descending from TControl, or be attached to an off-screen buffer from a TRasterImage descendent (TBitmap is the most commonly used). TFont, TBrush and TPen describe how the drawing of various operations will be executed in the Canvas.
TRasterImage (usually used via its descendant TBitmap) is a memory area reserved for drawing graphics, but it is created for maximum compatibility with the native Canvas and therefore in LCL-Gtk2 in X11 it is located in the X11 server, which makes pixel access via the Pixels property extremely slow. In Windows it is very fast because Windows allows creating a locally allocated image which can receive drawings from a Windows Canvas.
Besides these there are also non-native drawing classes located in the units graphtype (TRawImage), intfgraphics (TLazIntfImage) and lazcanvas (TLazCanvas, this one exists in Lazarus 0.9.31+). TRawImage is the storage and description of a memory area which contains an image. TLazIntfImage is an image which attaches itself to a TRawImage and takes care of converting between TFPColor and the real pixel format of the TRawImage. TLazCanvas is a non-native Canvas which can draw to an image in a TLazIntfImage.
The main difference between the native classes and the non-native ones is that the native ones do not perform exactly the same in all platforms, because the drawing is done by the underlying platform itself. The speed and also the exact final result of the image drawing can have differences. The non-native classes are guaranteed to perform exactly the same drawing in all platforms with a pixel level precision and they all perform reasonably fast in all platforms.
In the widgetset LCL-CustomDrawn the native classes are implemented using the non-native ones.
All of these classes will be better described in the sections below.
TCanvas로 작업하기
디�트 GUI �트 사용하기
다� 샘플코드로 사용� 가능하다:
SelectObject(Canvas.Handle, GetStockObject(DEFAULT_GUI_FONT));í�ì�´ ì œí•œë�œ í…�스트 그리기
DrawText 루틴� 사용해�, 처��는 DT_CALCRECT와 함께 다��는 없� 사용한다.
// First calculate the text size then draw it
TextBox := Rect(0, currentPos.Y, Width, High(Integer));
DrawText(ACanvas.Handle, PChar(Text), Length(Text),
TextBox, DT_WORDBREAK or DT_INTERNAL or DT_CALCRECT);
DrawText(ACanvas.Handle, PChar(Text), Length(Text),
TextBox, DT_WORDBREAK or DT_INTERNAL);ë‚ ì¹´ë¡œìš´ ì—�지를 가진 í…�스트 그리기(안티알리아싱 ì—†ì�Œ)
몇몇 ìœ„ì ¯ 다ì�Œì�„ 통해 ì�´ë¥¼ ì§€ì›�한다:
Canvas.Font.Quality:=fqNonAntialiasedgtk2 ê°™ì�€ 몇몇 ìœ„ì ¯ ì…‹ì�€ ì�´ë¥¼ ì§€ì›�하지 ì•Šê³ í•ìƒ� 엘리아스로 그린다. gtk2ì—�서 ë‚ ì¹´ë¡œìš´ 모서리를 가진 í…�스트를 그리는 간단한 procedureê°€ 있다. ëª¨ë“ ê²½ìš°ë¥¼ ê³ ë ¤í•œ 것ì�´ ì•„ë‹ˆê³ ì•„ì�´ë””ì–´ë§Œ ì œê³µí•œë‹¤:
procedure PaintAliased(Canvas: TCanvas; x,y: integer; const TheText: string);
var
w,h: integer;
IntfImg: TLazIntfImage;
Img: TBitmap;
dy: Integer;
dx: Integer;
col: TFPColor;
FontColor: TColor;
c: TColor;
begin
w:=0;
h:=0;
Canvas.GetTextSize(TheText,w,h);
if (w<=0) or (h<=0) then exit;
Img:=TBitmap.Create;
IntfImg:=nil;
try
// 비트맵� �스트를 그림
Img.Masked:=true;
Img.SetSize(w,h);
Img.Canvas.Brush.Style:=bsSolid;
Img.Canvas.Brush.Color:=clWhite;
Img.Canvas.FillRect(0,0,w,h);
Img.Canvas.Font:=Canvas.Font;
Img.Canvas.TextOut(0,0,TheText);
// 메모리 �미지를 얻어온다
IntfImg:=Img.CreateIntfImage;
// 회색 픽셀� 치환
FontColor:=ColorToRGB(Canvas.Font.Color);
for dy:=0 to h-1 do begin
for dx:=0 to w-1 do begin
col:=IntfImg.Colors[dx,dy];
c:=FPColorToTColor(col);
if c<>FontColor then
IntfImg.Colors[dx,dy]:=colTransparent;
end;
end;
// 비트맵 �성
Img.LoadFromIntfImage(IntfImg);
// 페�트
Canvas.Draw(x,y,Img);
finally
IntfImg.Free;
Img.Free;
end;
end;TBitmap과 다른 TGraphics ��으로 작업하기
TBitmap ê°�체는 스í�¬ë¦°ì—� 보여주기 ì „ì—� 비트맵ì�„ ì €ìž¥í•œë‹¤. 비트맵ì�„ ìƒ�ì„±í• ë•Œ 높ì�´ì™€ ë„“ì�´ë¥¼ ì§€ì •í•´ì•¼ë§Œ 하며 ì§€ì •í•˜ì§€ 않으면 í�¬ê¸°ëŠ” 0ì�´ ë�˜ê³ 아무것ë�„ 그릴 수 없게 ë�œë‹¤. ê·¸ë¦¬ê³ ì�¼ë°˜ì �으로 ëª¨ë“ ë‹¤ë¥¸ TRasterImage ì�˜ ìž�ì†�들ì�€ ë�™ì�¼í•œ ëŠ¥ë ¥ì�„ ì œê³µí•œë‹¤. 디스í�¬ì—�서 ìž…ì¶œë ¥í•˜ë ¤ëŠ” í�¬ë§·ê³¼ ì�¼ì¹˜í•˜ëŠ” 것ì�„ 사용하여야 하며 ê·¸ë ‡ì§€ 않다면 윈ë�„우즈 비트맵(*bmp)ì�¼ 경우 TBitmapì—� 관한 디스í�¬ ë�™ìž‘ì�€ 수행ë�˜ì§€ 않ì�„ 것ì�´ë‹¤.
(맨 ë¨¼ì € 기억해야 í• ê²ƒì�€ ë�¼ìž�루스는 플랫í�¼ì—� ë�…립ì �ì�´ë�¼ëŠ” 것ì�´ë¯€ë¡œ, 윈ë�„우즈 API 함수를 사용하는 ì–´ë– í•œ ë©”ì�¨ë“œë�„ 질문ì�˜ 대ìƒ�ì�´ 아니ë�¼ëŠ” 것ì�´ë‹¤. 그러므로 ScanLine ê°™ì�€ ë©”ì�¨ë“œëŠ” ë�¼ìž�루스ì—�서 ì§€ì›�하지 않는다. ë�¼ìž�루스는 장치 ë�…립ì �ì�¸ Bitmapê³¼ GDI32.dllì—� 있는 함수를 ì‚¬ìš©í•˜ê³ ìž� 하기 때문입니다
ë‹¹ì‹ ì�´ TBitmapì�˜ 높ì�´ì™€ í�ì�„ ì •ì�˜í•˜ì§€ 않았다면 그것ì�€ 표준ì �ì�¸ 것ì�´ê³ 매우 ìž‘ì�€ 것ì�´ë�¼ëŠ” 것ì�„ 명심해ë�¼)
Loading/Saving an image from/to the disk
To load an image from the disk use TGraphic.LoadFromFile and to save it to another disk file use TGraphic.SaveToFile. Use the appropriate TGraphic descendent which matches the format expected. See Developing_with_Graphics#Image_formats for a list of available image format classes.
var
MyBitmap: TBitmap;
begin
MyBitmap := TBitmap.Create;
try
// Load from disk
MyBitmap.LoadFromFile(MyEdit.Text);
// Here you can use MyBitmap.Canvas to read/write to/from the image
// Write back to another disk file
MyBitmap.SaveToFile(MyEdit2.Text);
finally
MyBitmap.Free;
end;
end;When using any other format the process is compelely identical, just use the adequate class. For example, for PNG images:
var
MyPNG: TPortableNetworkGraphic;
begin
MyPNG := TPortableNetworkGraphic.Create;
try
// Load from disk
MyPNG.LoadFromFile(MyEdit.Text);
// Here you can use MyPNG.Canvas to read/write to/from the image
// Write back to another disk file
MyPNG.SaveToFile(MyEdit2.Text);
finally
MyPNG.Free;
end;
end;If you don't know beforehand the format of the image, use TPicture which will determine the format based in the file extension. Note that TPicture does not support all formats supported by Lazarus, as of Lazarus 0.9.31 it supports BMP, PNG, JPEG, Pixmap and PNM while Lazarus also supports ICNS and other formats:
var
MyPicture: TPicture;
begin
MyPicture := TPicture.Create;
try
// Load from disk
MyPicture.LoadFromFile(MyEdit.Text);
// Here you can use MyPicture.Graphic.Canvas to read/write to/from the image
// Write back to another disk file
MyPicture.SaveToFile(MyEdit2.Text);
finally
MyPicture.Free;
end;
end;Direct pixel access
To do directly access the pixels of bitmaps one can either use external libraries, such as BGRABitmap, LazRGBGraphics and Graphics32 or use the Lazarus native TLazIntfImage. For a comparison of pixel access methods, see fast direct pixel access.
On some Lazarus widgetsets (notably LCL-Gtk2), the bitmap data is not stored in memory location which can be accessed by the application and in general the LCL native interfaces draw only through native Canvas routines, so each SetPixel / GetPixel operation involves a slow call to the native Canvas API. In LCL-CustomDrawn this is not the case since the bitmap is locally stored for all backends and SetPixel / GetPixel is fast. For obtaining a solution which works in all widgetsets one should use TLazIntfImage. As Lazarus is meant to be platform independent and work in gtk2, the TBitmap class does not provide a property like Scanline. There is a GetDataLineStart function, equivalent to Scanline, but only available for memory images like TLazIntfImage which internally uses TRawImage.
To sum it up, with the standard TBitmap, you can only change pixels indirectly, by using TCanvas.Pixels. Calling a native API to draw / read an individual pixel is course slower than direct pixel access, notably so in LCL-gtk2 and LCL-Carbon.
컬러가 투명한 비트맵 그리기
ë�¼ìž�루스 0.9.11ì—�서 구현ë�œ 새로운 특징ì�€ 컬러 투명한 비트맵ì�´ë‹¤. 비트맵 파ì�¼(*.BMP)파ì�¼ì�€ 투명ë�„를 ì €ìž¥ í• ìˆ˜ 있는 ì–´ë– í•œ ì •ë³´ë�„ ì €ìž¥í• ìˆ˜ 없지만, 투명ì˜�ì—ì�„ 표현하기위한 컬러를 ì„ íƒ�한다면 ê·¸ ì •ë³´ë¥¼ 가진 것 처럼 ë�™ìž‘한다. ì�´ê²ƒì�€ Win32 어플리케ì�´ì…˜ì—�서 사용ë�œ ì�¼ë°˜ì �ì�¸ 트ë¦ì�´ë‹¤.
다ì�Œ ì˜ˆì œëŠ” 윈ë�„우즈 리소스ì—�서 비트맵ì�„ ë¡œë“œí•˜ê³ , 투명하기 ì›�하는 색ìƒ�(clFuchsia)ì�„ ì„ íƒ�í•˜ê³ ê·¸ê²ƒì�„ 캔버스ì—� 그린다.
procedure MyForm.MyButtonOnClick(Sender: TObject);
var
buffer: THandle;
bmp: TBitmap;
memstream: TMemoryStream;
begin
bmp := TBitmap.Create;
buffer := Windows.LoadBitmap(hInstance, MAKEINTRESOURCE(ResourceID));
if (buffer = 0) then exit; // 비트맵� 로딩하다가 �러
bmp.Handle := buffer;
memstream := TMemoryStream.create;
try
bmp.SaveToStream(memstream);
memstream.position := 0;
bmp.LoadFromStream(memstream);
finally
memstream.free;
end;
bmp.Transparent := True;
bmp.TransparentColor := clFuchsia;
MyCanvas.Draw(0, 0, bmp);
bmp.Free; // í• ë‹¹ë�œ 비트맵ì�„ í•´ì œí•œë‹¤.
end;메모리 í• ë‹¹ì�€ TMemoryStream으로 수행한다는 것ì�„ 명심하ë�¼. ì�´ë¯¸ì§€ë¥¼ ì •í™•ížˆ 로딩하는지 확ì�¸í•˜ëŠ” 것ì�€ 필수ì�´ë‹¤.
스�린� 스�린 샷 얻기
ë�¼ìž�루스 0.9.16 ì�´ëž˜í�¬ë¡œìФ 플랫í�¼ìƒ�ì—�서 스í�¬ë¦°ì�˜ 스í�¬ë¦°ìƒ·ì�„ 얻기 위해 LCLì�„ ì‚¬ìš©í• ìˆ˜ 있다. 다ì�Œ ì˜ˆì œ 코드가 ê·¸ë ‡ê²Œ 한다(gtk2와 win32ìƒ�ì—�서 ë�™ìž‘하지만, gtk1ì—�서는 현재 ë�™ìž‘하지 않는다):
uses LCLIntf, LCLType;
...
var
MyBitmap: TBitmap;
ScreenDC: HDC;
begin
MyBitmap := TBitmap.Create;
ScreenDCÂ := GetDC(0);
MyBitmap.LoadFromDevice(ScreenDC);
ReleaseDC(ScreenDC);
...서서히 사�지는 예
Fading 그림ì�„ ë§Œë“¤ë ¤ê³ í•œë‹¤ë©´, ë�¸íŒŒì�´ì—�서는 다ì�Œê³¼ ê°™ì�„ 것ì�´ë‹¤:
`
type
PRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..32767] of TRGBTriple;
procedure TForm1.FadeIn(aBitMap: TBitMap);
var
Bitmap, BaseBitmap: TBitmap;
Row, BaseRow: PRGBTripleArray;
x, y, step: integer;
begin
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32bit; // pf24bit
Bitmap.Assign(aBitMap);
BaseBitmap := TBitmap.Create;
try
BaseBitmap.PixelFormat := pf32bit;
BaseBitmap.Assign(Bitmap);
for step := 0 to 32 do begin
for y := 0 to (Bitmap.Height - 1) do begin
BaseRow := BaseBitmap.Scanline[y];
Row := Bitmap.Scanline[y];
for x := 0 to (Bitmap.Width - 1) do begin
Row[x].rgbtRed := (step * BaseRow[x].rgbtRed) shr 5;
Row[x].rgbtGreen := (step * BaseRow[x].rgbtGreen) shr 5; // Fading
Row[x].rgbtBlue := (step * BaseRow[x].rgbtBlue) shr 5;
end;
end;
Form1.Canvas.Draw(0, 0, Bitmap);
InvalidateRect(Form1.Handle, nil, False);
RedrawWindow(Form1.Handle, nil, 0, RDW_UPDATENOW);
end;
finally
BaseBitmap.Free;
end;
finally
Bitmap.Free;
end;
end;
`` ��루스�서 � 함수는 다�과 같� 구현�다:uses LCLType, // HBitmap 타입 IntfGraphics, // TLazIntfImage 타입 fpImage; // TFPColor 타입 ... procedure TForm1.FadeIn(ABitMap: TBitMap); var SrcIntfImg, TempIntfImg: TLazIntfImage; ImgHandle,ImgMaskHandle: HBitmap; FadeStep: Integer; px, py: Integer; CurColor: TFPColor; TempBitmap: TBitmap; begin SrcIntfImg:=TLazIntfImage.Create(0,0); SrcIntfImg.LoadFromBitmap(ABitmap.Handle,ABitmap.MaskHandle); TempIntfImg:=TLazIntfImage.Create(0,0); TempIntfImg.LoadFromBitmap(ABitmap.Handle,ABitmap.MaskHandle); TempBitmap:=TBitmap.Create; for FadeStep:=1 to 32 do begin for py:=0 to SrcIntfImg.Height-1 do begin for px:=0 to SrcIntfImg.Width-1 do begin CurColor:=SrcIntfImg.Colors[px,py]; CurColor.Red:=(CurColor.RedFadeStep) shr 5; CurColor.Green:=(CurColor.GreenFadeStep) shr 5; CurColor.Blue:=(CurColor.Blue*FadeStep) shr 5; TempIntfImg.Colors[px,py]:=CurColor; end; end; TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false); TempBitmap.Handle:=ImgHandle; TempBitmap.MaskHandle:=ImgMaskHandle; Canvas.Draw(0,0,TempBitmap); end; SrcIntfImg.Free; TempIntfImg.Free; TempBitmap.Free; end;
ì�´ 페ì�´ì§€ì�˜ ë�¼ìž�루스 코드는 $LazarusPath/examples/lazintfimage/fadein1.lpi 프로ì �트ì—�서 ê°€ì ¸ì˜¨ 것ì�´ë‹¤. 그러므로 만약 ìž˜í•˜ê³ ì‹¶ë‹¤ë©´ ì�´ ì˜ˆì œë¥¼ ìž�세히 ë³´ê³ ê·¸ëž˜í”½ 프로그래ë°�ì�„ 시작하ë�¼.
### TLazIntfImage를 Canvas� 그리기
ScanLines ì†�성 ì�¼ì‹œì �으로 TBitmapì—�서 ì‚ì œ ë�˜ì—ˆê¸° 때문ì—�, Bitmap scanline ë�°ì�´í„°ì—� ì ‘ê·¼í•˜ê¸° 위한 ìœ ì�¼í•œ 방법ì�€ TLazIntfImage를 사용하는 것ì�´ë‹¤. 다ì�Œì�€ TBitmapì—�서 TLazIntfImage ì�„ ìƒ�성하는 방법ì—� 대한 것과 Canvasì—� TLazIntfImageì—� 그리는 방법ì—� 대한 예ì�´ë‹¤.uses ...GraphType, IntfGraphics, LCLType, LCLProc, LCLIntf ...
procedure TForm1.Button4Click(Sender: TObject);
var
b: TBitmap;
t: TLazIntfImage;
bmp, old: HBitmap;
msk: HBitmap;
tmpDC: HDC;
begin
b := TBitmap.Create;
try
b.LoadFromFile('test.bmp');
t := b.CreateIntfImage;
t.CreateBitmaps(bmp, msk, false);tmpDCÂ := CreateCompatibleDC(Canvas.Handle);
old := SelectObject(tmpDC, bmp);
BitBlt(Canvas.Handle, 0, 0, t.Width, t.Height, tmpDC, 0, 0, SRCCOPY);
DeleteObject(SelectObject(tmpDC, old));
DeleteObject(msk);
DeleteDC(tmpDC);finally
t.Free;
b.Free;
end;end;
## Working with TLazIntfImage, TRawImage and TLazCanvas
TLazIntfImage is a non-native equivalent of TRasterImage (more commonly utilized in the form of it's descendent TBitmap). The first thing to be aware about this class is that unlike TBitmap it will not automatically allocate a memory area for the bitmap, one should first initialize a memory area and then give it to the TLazIntfImage. Right after creating a TLazIntfImage one should either connect it to a TRawImage or load it from a TBitmap.
TRawImage is of the type object and therefore does not need to be created nor freed. It can either allocate the image memory itself when one calls TRawImage.CreateData or one can pass a memory block allocated for examply by a 3rd party library such as the Windows API of the Cocoa Framework from Mac OS X and pass the information of the image in TRawImage.Description, TRawImage.Data and TRawImage.DataSize. Instead of attaching it to a RawImage one could also load it from a TBitmap which will copy the data from the TBitmap and won't be syncronized with it afterwards. The TLazCanvas cannot exist alone and must always be attached to a TLazIntfImage.
The example below shows how to choose a format for the data and ask the TRawImage to create it for us and then we attach it to a TLazIntfImage and then attach a TLazCanvas to it:uses graphtype, intfgraphics, lazcanvas;
var
AImage: TLazIntfImage;
ACanvas: TLazCanvas;
lRawImage: TRawImage;
begin
lRawImage.Init;
lRawImage.Description.Init_BPP32_A8R8G8B8_BIO_TTB(AWidth, AHeight);
lRawImage.CreateData(True);
AImage := TLazIntfImage.Create(0,0);
AImage.SetRawImage(lRawImage);
ACanvas := TLazCanvas.Create(AImage);
### Initializing a TLazIntfImage
One cannot simply create an instance of TLazIntfImage and start using it. It needs to add a storage to it. There are 3 ways to do this:
1\. Attach it to a TRawImage
2\. Load it from a TBitmap. Note that it will copy the memory of the TBitmap so it won't remain connected to it.SrcIntfImg:=TLazIntfImage.Create(0,0); SrcIntfImg.LoadFromBitmap(ABitmap.Handle,ABitmap.MaskHandle);
3\. Load it from a raw image description, like this:IntfImg := TLazIntfImage.Create(0,0); IntfImg.DataDescription:=GetDescriptionFromDevice(0); IntfImg.SetSize(10,10);
The 0 device in **GetDescriptionFromDevice(0)** uses the current screen format.
### TLazIntfImage.LoadFromFile
Here is an example how to load an image directly into a TLazIntfImage. It initializes the TLazIntfImage to a 32bit RGBA format. Keep in mind that this is probably not the native format of your screen.uses LazLogger, Graphics, IntfGraphics, GraphType; procedure TForm1.FormCreate(Sender: TObject); var AImage: TLazIntfImage; lRawImage: TRawImage; begin // create a TLazIntfImage with 32 bits per pixel, alpha 8bit, red 8 bit, green 8bit, blue 8bit, // Bits In Order: bit 0 is pixel 0, Top To Bottom: line 0 is top lRawImage.Init; lRawImage.Description.Init_BPP32_A8R8G8B8_BIO_TTB(0,0); lRawImage.CreateData(false); AImage := TLazIntfImage.Create(0,0); try AImage.SetRawImage(lRawImage); // Load an image from disk. // It uses the file extension to select the right registered image reader. // The AImage will be resized to the width, height of the loaded image. AImage.LoadFromFile('lazarus/examples/openglcontrol/data/texture1.png'); debugln(['TForm1.FormCreate ',AImage.Width,' ',AImage.Height]); finally AImage.Free; end; end;
### Loading a TLazIntfImage into a TImage
The pixel data of a **TImage** is the **TImage.Picture** property, which is of type _TPicture_. **TPicture** is a multi format container containing one of several common image formats like Bitmap, Icon, Jpeg or PNG . Usually you will use the _TPicture.Bitmap_ to load a **TLazIntfImage** :Image1.Picture.Bitmap.LoadFromIntfImage(IntfImg);
**Notes:**
* To load a **transparent** TLazIntfImage you have to set the **Image1.Transparent** to true.
* TImage uses the screen format. If the TLazIntfImage has a different format then the pixels will be converted. Hint: You can use **IntfImg.DataDescription:=GetDescriptionFromDevice(0);** to initialize the TLazIntfImage with the screen format.
### 서서히 사ë�¼ì§€ëŠ” ì˜ˆì œ
TLazIntfImage를 ì�´ìš©í•œ 서서히 사ë�¼ì§€ëŠ” ì˜ˆì œ{ This code has been taken from the $LazarusPath/examples/lazintfimage/fadein1.lpi project. } uses LCLType, // HBitmap 타입 IntfGraphics, // TLazIntfImage 타입 fpImage; // TFPColor 타입 ... procedure TForm1.FadeIn(ABitMap: TBitMap); var SrcIntfImg, TempIntfImg: TLazIntfImage; ImgHandle,ImgMaskHandle: HBitmap; FadeStep: Integer; px, py: Integer; CurColor: TFPColor; TempBitmap: TBitmap; begin SrcIntfImg:=TLazIntfImage.Create(0,0); SrcIntfImg.LoadFromBitmap(ABitmap.Handle,ABitmap.MaskHandle); TempIntfImg:=TLazIntfImage.Create(0,0); TempIntfImg.LoadFromBitmap(ABitmap.Handle,ABitmap.MaskHandle); TempBitmap:=TBitmap.Create; for FadeStep:=1 to 32 do begin for py:=0 to SrcIntfImg.Height-1 do begin for px:=0 to SrcIntfImg.Width-1 do begin CurColor:=SrcIntfImg.Colors[px,py]; CurColor.Red:=(CurColor.RedFadeStep) shr 5; CurColor.Green:=(CurColor.GreenFadeStep) shr 5; CurColor.Blue:=(CurColor.Blue*FadeStep) shr 5; TempIntfImg.Colors[px,py]:=CurColor; end; end; TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false); TempBitmap.Handle:=ImgHandle; TempBitmap.MaskHandle:=ImgMaskHandle; Canvas.Draw(0,0,TempBitmap); end; SrcIntfImg.Free; TempIntfImg.Free; TempBitmap.Free; end;
### Image format specific example
If you know that the TBitmap is using blue 8bit, green 8bit, red 8bit you can directly access the bytes, which is somewhat faster:uses LCLType, // HBitmap type IntfGraphics, // TLazIntfImage type fpImage; // TFPColor type ... type TRGBTripleArray = array[0..32767] of TRGBTriple; PRGBTripleArray = ^TRGBTripleArray;
procedure TForm1.FadeIn2(aBitMap: TBitMap);
var
IntfImg1, IntfImg2: TLazIntfImage;
ImgHandle,ImgMaskHandle: HBitmap;
FadeStep: Integer;
px, py: Integer;
CurColor: TFPColor;
TempBitmap: TBitmap;
Row1, Row2: PRGBTripleArray;
begin
IntfImg1:=TLazIntfImage.Create(0,0);
IntfImg1.LoadFromBitmap(aBitmap.Handle,aBitmap.MaskHandle);IntfImg2:=TLazIntfImage.Create(0,0);
IntfImg2.LoadFromBitmap(aBitmap.Handle,aBitmap.MaskHandle);TempBitmap:=TBitmap.Create;//with Scanline-like
for FadeStep:=1 to 32 do begin
for py:=0 to IntfImg1.Height-1 do begin
Row1 := IntfImg1.GetDataLineStart(py); //like Delphi TBitMap.ScanLine
Row2 := IntfImg2.GetDataLineStart(py); //like Delphi TBitMap.ScanLine
for px:=0 to IntfImg1.Width-1 do begin
Row2^[px].rgbtRed:= (FadeStep * Row1^[px].rgbtRed) shr 5;
Row2^[px].rgbtGreen := (FadeStep * Row1^[px].rgbtGreen) shr 5; // Fading
Row2^[px].rgbtBlue := (FadeStep * Row1^[px].rgbtBlue) shr 5;
end;
end;
IntfImg2.CreateBitmaps(ImgHandle,ImgMaskHandle,false);TempBitmap.Handle:=ImgHandle;
TempBitmap.MaskHandle:=ImgMaskHandle;
Canvas.Draw(0,0,TempBitmap);end;IntfImg1.Free;
IntfImg2.Free;
TempBitmap.Free;end;
### Conversion between TLazIntfImage and TBitmap
Since Lazarus has no TBitmap.ScanLines property, the best way to access the pixels of an image in a fast way for both reading and writing is by using TLazIntfImage. The TBitmap can be converted to a TLazIntfImage by using TBitmap.CreateIntfImage() and after modifying the pixels it can be converted back to a TBitmap by using TBitmap.LoadFromIntfImage(); Here's the sample on how to create TLazIntfImage from TBitmap, modify it and then go back to the TBitmap.uses ...GraphType, IntfGraphics, LCLType, LCLProc, LCLIntf ...
procedure TForm1.Button4Click(Sender: TObject);
var
b: TBitmap;
t: TLazIntfImage;
begin
b := TBitmap.Create;
try
b.LoadFromFile('test.bmp');
t := b.CreateIntfImage;// Read and/or write to the pixels
t.Colors[10,20] := colGreen;b.LoadFromIntfImage(t);finally
t.Free;
b.Free;
end;end;
### Using the non-native StretchDraw from LazCanvas
Just like TCanvas.StretchDraw there is TLazCanvas.StretchDraw but you need to specify the interpolation which you desire to use. The interpolation which provides a Windows-like StretchDraw with a very sharp result (the opposite of anti-aliased) can be added with: TLazCanvas.Interpolation := TFPSharpInterpolation.Create;
There are other interpolations available in the unit fpcanvas.uses intfgraphics, lazcanvas;
procedure TForm1.StretchDrawBitmapToBitmap(SourceBitmap, DestBitmap: TBitmap; DestWidth, DestHeight: integer);
var
DestIntfImage, SourceIntfImage: TLazIntfImage;
DestCanvas: TLazCanvas;
begin
// Prepare the destinationDestIntfImage := TLazIntfImage.Create(0, 0);
DestIntfImage.LoadFromBitmap(DestBitmap.Handle, 0);DestCanvas := TLazCanvas.Create(DestIntfImage);//Prepare the source
SourceIntfImage := TLazIntfImage.Create(0, 0);
SourceIntfImage.LoadFromBitmap(SourceBitmap.Handle, 0);// Execute the stretch draw via TFPSharpInterpolation
DestCanvas.Interpolation := TFPSharpInterpolation.Create;
DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);// Reload the image into the TBitmap
DestBitmap.LoadFromIntfImage(DestIntfImage);SourceIntfImage.Free;
DestCanvas.Interpolation.Free;
DestCanvas.Free;
DestIntfImage.Free;end;procedure TForm1.FormPaint(Sender: TObject);
var
Bmp, DestBitmap: TBitmap;
begin
// Prepare the destination
DestBitmap := TBitmap.Create;
DestBitmap.Width := 100;
DestBitmap.Height := 100;Bmp := TBitmap.Create;
Bmp.Width := 10;
Bmp.Height := 10;
Bmp.Canvas.Pen.Color := clYellow;
Bmp.Canvas.Brush.Color := clYellow;
Bmp.Canvas.Rectangle(0, 0, 10, 10);
StretchDrawBitmapToBitmap(Bmp, DestBitmap, 100, 100);
Canvas.Draw(0, 0, Bmp);
Canvas.Draw(100, 100, DestBitmap);end;
## 모션 그래픽 - 플리커�� 피하는 방법
ë§Žì�€ 프로그램ì�´ 2D 그래픽ì�„ GUIì—� ì¶œë ¥í•˜ì—¬ 그린다. ì�´ 그래픽ì�„ 빨리 ë³€í™˜í•˜ê³ ìž� 한다면 ê³§ ë¬¸ì œì—� ë´‰ì°©í• ê²ƒì�´ë‹¤: ë¹ ë¥´ê²Œ 변환하는 그래픽ì�€ 종종 스í�¬ë¦°ì�„ 번ì©�ì�´ê²Œ 한다. ì�´ëŸ¬í•œ ìƒ�황ì�€ ê°€ë�” ì „ì²´ ì�´ë¯¸ì§€ë¥¼ 보거나 ê°€ë�”ì�€ 부분ì �으로 ê·¸ë ¤ì§ˆ 때 ì�¼ì–´ë‚œë‹¤. ì�´ëŠ” 그림ì�„ 그리는 시간ì�´ 필요하기 때문ì—� ì�¼ì–´ë‚˜ëŠ” 것ì�´ë‹¤.
하지만 번ì©�ìž„ì�„ 어떻게 í”¼í•˜ê³ ìµœì �ì�˜ 드로잉 ì†�ë�„를 ì–»ì�„ 수 있ì�„까? ë¬¼ë¡ OpenGLì�„ ì�´ìš©í•œ 하드웨어 ê°€ì†� 기능ì�„ ì‚¬ìš©í• ìˆ˜ 있지만, ì�´ëŸ¬í•œ ì ‘ê·¼ë²•ì�€ ìž‘ì�€ 프로그램 ë˜�는 구형 컴퓨터ì—�서는 꽤 ì–´ë ¤ìš´ ë¬¸ì œê°€ ë�˜ê¸°ë�„ 한다. OpenGLì�˜ ë�„움ì�„ 받는다면 ë�¼ìž�루스ì—� ë”¸ë ¤ì˜¤ëŠ” ì˜ˆì œë¥¼ 살펴보면 ë�œë‹¤. ë˜�한 A.J. Venterì�˜ gamepack를 ì‚¬ìš©í• ìˆ˜ 있는ë�°, ë�”블 버í�¼ 캔버스와 스프ë�¼ì�´íЏ ì»´í�¬ë„ŒíŠ¸ë¥¼ ì œê³µí•œë‹¤.
Canvasì—� 그리기 위해서는 ì œê³µë�˜ëŠ” 옵션 등ì�„ ì�´ì œ 시험해 ë³¼ 것ì�´ë‹¤:
* TImage� 그리기
* �, TPaintBox �는 다른 컨트롤� OnPaint� 그리기
* ìž�ì²´ì �으로 그릴 수 있는 커스텀 컨트롤 ìƒ�성하기
* A.J. Venter� 게임팩 사용하기
### TImage� 그리기
TImage는 ë‘�ê°œ 파트로 구성ë�œë‹¤. TGraphic, 종종 TBitmap,ì�€ ì˜�구ì �ì�¸ 그림과 비주얼 ì˜�ì—ì�„ 가지며 OnPaint 때마다 다시 ê·¸ë ¤ì§„ë‹¤. TImageì�˜ í�¬ê¸°ë¥¼ 바꾸면 bitmapì�˜ í�¬ê¸°ë¥¼ 바꾸지 **않는다**. 그래픽(ë˜�는 비트맵)ì�€ Image1.Picture.Graphic (ë˜�는 Image1.Picture.Bitmap)ì�„ 통해 ì ‘ê·¼í• ìˆ˜ 있다. 캔버스는 Image1.Picture.Bitmap.Canvasì�´ë‹¤. TImageì�˜ 비주얼 ì˜�ì—ì�˜ 캔버스는 Image1.Canvas를 통해 Image1.OnPaint ë�™ì•ˆì—�ë§Œ ì ‘ê·¼ í• ìˆ˜ 있다.
**중요** : TImageì�˜ graphic/bitmapì—� 그리기 위해 Image1 ì�´ë²¤íЏì�˜ OnPaint를 사용하면 안ë�œë‹¤. TImageì�˜ graphicì�€ 버í�¼ì—� ë³´ê´€ ë�˜ë¯€ë¡œ, í•˜ê³ ìž� 하는 ëª¨ë“ ê²ƒì�€ ì–´ëŠ� ê³³ì—�서ë�˜ì§€ ê·¸ë ¤ì§€ê³ ë³€í™”ëŠ” ì˜�구ì �ì�¸ 것ì�´ ë�œë‹¤. 그러나 만약 í•ìƒ� 다시 그린다면 ì�´ë¯¸ì§€ëŠ” 번ì©�ì�´ê²Œ ë� 것ì�´ë‹¤. ì�´ëŸ° 경우 다른 옵션ì�„ 시ë�„해야 한다. TImageì—� 그리는 것ì�€ 다른 ì ‘ê·¼ë²•ë³´ë‹¤ ëŠ�ë¦¬ë‹¤ê³ ì—¬ê²¨ì§„ë‹¤.
#### TImage� 비트맵� �기 변경
Note: OnPaint�안 �것� 사용하지 마�.with Image1.Picture.Bitmap do begin Width:=100; Height:=120; end;
#### TImage� 비트맵� 페�팅하기
Note: OnPaintë�™ì•ˆ ì�´ê²ƒì�„ 사용하지 마ë�¼.with Image1.Picture.Bitmap.Canvas do begin // ëª¨ë“ ë¹„íŠ¸ë§µì�„ 빨강으로 채우기 Brush.Color:=clRed; FillRect(0,0,Width,Height); end;
Note: Image1.OnPaintì�˜ ë‚´ë¶€ì—�서 Image1.Canvasì�€ volatile visible ì˜�ì—ì�„ 가리킨다. Image1.OnPaintì�˜ 외부ì—�서는 Image1.Canvas는 Image1.Picture.Bitmap.Canvas를 가리킨다.
다른 예:
` `
`procedure TForm1.BitBtn1Click(Sender: TObject); var x, y: Integer; begin // 배경 그리기 MyImage.Canvas.Pen.Color := clWhite; MyImage.Canvas.Rectangle(0, 0, Image.Width, Image.Height);
// 사�형 그리기
MyImage.Canvas.Pen.Color := clBlack;
for x := 1 to 8 do
for y := 1 to 8 do
MyImage.Canvas.Rectangle(Round((x - 1) * Image.Width / 8), Round((y - 1) * Image.Height / 8),
Round(x * Image.Width / 8), Round(y * Image.Height / 8));end;``
TImageì�˜ volatile visual ì˜�ì—ì—� 페ì�¸íŒ…하기
OnPaint ë�™ì•ˆ ì�´ ì˜�ì—ì—�ë§Œ 페ì�¸íЏ í• ìˆ˜ 있다. ê·¸ ì˜�ì—ì�´ 무효화 ë� 때 ê²°êµ LCLì�€ ìž�ë�™ìœ¼ë¡œ OnPaint를 부른다. Image1.Invalidate로 수ë�™ì �으로 ê·¸ ì—¬ì—ì�„ 무효화 시킬 수 있다.ì�´ëŠ” 즉시 OnPaint를 부르는 것ì�´ 아니므로 ì›�í• ë•Œë§ˆë‹¤ Invalidate를 부를 수 있다.
procedure TForm.Image1Paint(Sender: TObject);
begin
with Image1.Canvas do begin
// ì„ ì�„ 페ì�¸íŠ¸í•œë‹¤.
Pen.Color:=clRed;
Line(0,0,Width,Height);
end;
end;OnPaint �벤트� 그리기
ì�´ 경우 ëª¨ë“ ë“œë¡œìž‰ì�€ í�¼ì�˜ OnPaint ì�´ë²¤íЏì—�서 ì�´ë£¨ì–´ì ¸ì•¼ 한다. TImage 처럼 버í�¼ì—� 남아있지 않는다.
ìž�ì²´ì �으로 그릴 수 있는 커스텀 컨트롤 ìƒ�성하기
커스텀 컨트롤ì�„ ìƒ�성하는 것ì�€ 코드를 구조화 시키는 장ì �ì�´ 있으며 컨트롤ì�„ ìž¬ì‚¬ìš©í• ìˆ˜ 있다. ì�´ ì ‘ê·¼ 법ì�€ 매우 ë¹ ë¥´ì§€ë§Œ TBitmapì�„ ë¨¼ì € 그리지 ì•Šê³ ìº”ë²„ìŠ¤ì—� 그린다면 ì—¬ì „ížˆ 번ì©�ìž„ì�´ ë‚˜íƒ€ë‚ ê²ƒì�´ë‹¤. ì�´ëŸ¬í•œ 경우 컨트롤ì�˜ OnPaint ì�´ë²¤íŠ¸ë¥¼ ì‚¬ìš©í• í•„ìš”ê°€ 없다.
다ì�Œì�€ 커스텀 컨트롤ì—� 대한 ì˜ˆì œì�´ë‹¤:
`
uses
Classes, SysUtils, Controls, Graphics, LCLType;
type
TMyDrawingControl = class(TCustomControl)
public
procedure EraseBackground(DC: HDC); override;
procedure Paint; override;
end;
implementation
procedure TMyDrawingControl.EraseBackground(DC: HDC);
begin
// ë””í�´íЏ ë°°ê²½ 지우기를 가능하게 í•˜ë ¤ë©´ 다ì�Œì�˜ 코멘트를 지워ë�¼
//inherited EraseBackground(DC);
end;
procedure TMyDrawingControl.Paint;
var
x, y: Integer;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
// Bitmap �기 초기화
Bitmap.Height := Height;
Bitmap.Width := Width;
// 배경 그리기
Bitmap.Canvas.Pen.Color := clWhite;
Bitmap.Canvas.Rectangle(0, 0, Width, Height);
// 사�형 그리기
Bitmap.Canvas.Pen.Color := clBlack;
for x := 1 to 8 do
for y := 1 to 8 do
Bitmap.Canvas.Rectangle(Round((x - 1) * Width / 8), Round((y - 1) * Height / 8),
Round(x * Width / 8), Round(y * Height / 8));
Canvas.Draw(0, 0, Bitmap);
finally
Bitmap.Free;
end;
inherited Paint;
end;
``
ê·¸ë¦¬ê³ ê·¸ê²ƒì�„ í�¼ìƒ�ì—� ìƒ�성하는 방법ì�´ë‹¤:
` `
`procedure TMyForm.FormCreate(Sender: TObject); begin MyDrawingControl:= TMyDrawingControl.Create(Self); MyDrawingControl.Height := 400; MyDrawingControl.Width := 500; MyDrawingControl.Top := 0; MyDrawingControl.Left := 0; MyDrawingControl.Parent := Self; MyDrawingControl.DoubleBuffered := True; end;
``
í•´ì œí•˜ëŠ” 것ì�„ 잊으면 안ë�œë‹¤:
`
procedure TMyForm.FormDestroy(Sender: TObject);
begin
MyDrawingControl.Free;
end;
``
ì�´ê²ƒì�€ 표준 위치ì—� 있기 때문ì—�, Topê³¼ Left를 0으로 ì„¤ì •í• í•„ìš”ëŠ” 없지만, 컨트롤ì�´ 놓ì�¼ ê³³ì�„ ì§€ì •í•˜ê¸° 위해서는 ê·¸ë ‡ê²Œ 해야 한다.
"MyDrawingControl.Parent := Self;" 는 메우 중요하므로 ê·¸ë ‡ê²Œ 하지 않는다면 컨트롤ì�„ ë³¼ 수 ì—†ì�„ 것ì�´ë‹¤.
"MyDrawingControl.DoubleBuffered := True;"ì�€ 윈ë�„ìš°ì—�서 번ì©�ìž„ì�„ í”¼í• ë ¤ë©´ 필요하다. gtkì—�서는 ë�™ìž‘하지 않는다.
### A.J. Venter� 게임팩 사용하기
게임팩 ì ‘ê·¼ë²•ì�€ 한개ì�˜ ë�”블 버í�¼ë�œ 캔버스ì—� ëª¨ë“ ê²ƒì�„ 그리는 것으로, 준비ë�œ, 보여지는 캔버스만 ì—…ë�°ì�´íЏ ë�œë‹¤. ì�´ê²ƒì�€ 매우 ì§§ì�€ 코드로 구현ë�˜ì§€ë§Œ, ë§Žì�€ 수ì�˜ 스프ë�¼ì�´íŠ¸ê°€ ë„“ì�€ 범위ì—�서 ë¹ ë¥´ê²Œ 변화하는 장면ì�„ 가능하게 해주는 잇ì �ì�´ 있다. ì�´ëŸ¬í•œ ì ‘ê·¼ë²•ì�„ ì‚¬ìš©í•˜ë ¤ë©´,A.J. Venterì�˜ gamepackì—� 관심ì�´ 있ì�„ 것ì�´ë‹¤. ì�´ëŠ” ë�¼ìž�우스ì—�서 게임ì�„ ê°œë°œí• ìˆ˜ 있는 게임 ì»´í�¬ë„ŒíŠ¸ë¡œì„œ 스프ë�¼ì�´íЏ ì»´í�¬ë„ŒíЏë¿�ë§Œì�´ 아니ë�¼ ë�”블-버í�¼ ë””ìŠ¤í”Œë ˆì�´ ì˜�ì—ì�„ ì œê³µí•´ 주며 서로 서로 잘 통합ë�˜ë�„ë¡� ë””ìž�ì�¸ ë�˜ì—ˆë‹¤. 게임팩ì�€ subversion:
ì�„ 통해 êµ¬í• ìˆ˜ 있다.
` svn co <svn://silentcoder.co.za/lazarus/gamepack> ` 추가ì �ì�¸ ì •ë³´ì™€ 문서 ê·¸ë¦¬ê³ ë‹¤ìš´ë¡œë“œëŠ” [홈페ì�´ì§€](<http://outkastsolutions.co.za/outkast/index.php?option=com_openwiki&Itemid=&id=gamepack>)ì—�서 êµ¬í• ìˆ˜ 있다.
## �미지 �맷
ê°� ì�´ë¯¸ì§€ í�¬ë§·ì�„ 사용하기 위한 ì �당한 í�´ëž˜ìФì�˜ í…Œì�´ë¸”ì�´ 여기 있다.
í�¬ë§· | ì�´ë¯¸ì§€ í�´ëž˜ìФ | ìœ ë‹›
---|---|---
커서(cur) | TCursor | Graphics
비트맵(bmp) | TBitmap | Graphics
윈�우즈 아�콘 (ico) | TIcon | Graphics
Mac OS X 아�콘(icns) | TicnsIcon | Graphics
Pixmap (xpm) | TPixmap | Graphics
Portable Network Graphic (png) | TPortableNetworkGraphic | Graphics
JPEG (jpg, jpeg) | TJpegImage | Graphics
PNM (pnm) | TPortableAnyMapGraphic | Graphics
[[fcl-image|fcl-image 지� �맷]] 리스트를 보세요.
### �맷 변환
ê°€ë�” 그래픽 í�¬ë§·ì�„ 다른 형ì‹�으로 변환해야 í• ë•Œê°€ 있다. 한가지 방법ì�€ 그래픽ì�„ 중간 형ì‹�으로 바꾼 후 TBitmap으로 변환하는 것ì�´ë‹¤. 대부분ì�˜ í�¬ë§·ì�€ TBitmapì—�서 만들어질 수 있다.
Bitmapì�„ PNG로 ë³€í™˜í•˜ê³ íŒŒì�¼ì—� ì €ìž¥í•˜ëŠ” 것:procedure SaveToPng(const bmp: TBitmap; PngFileName: String); var png : TPortableNetworkGraphic; begin png := TPortableNetworkGraphic.Create; try png.Assign(bmp); png.SaveToFile(PngFileName); finally png.Free; end; end;
## 픽셀 �맷
### TColor
LCLì—�서 TColor를 위한 ë‚´ë¶€ 픽셀 í�¬ë§·ì�€ XXBBGGRR í�¬ë§·ìœ¼ë¡œ 네ì�´í‹°ë¸Œ 윈ë�„우즈 í�¬ë§·ì—� 대ì�‘하며 AARRGGBB를 사용하는 대부분ì�˜ 다른 ë�¼ì�´ë¸ŒëŸ¬ë¦¬ì™€ëŠ” 반대ì�´ë‹¤. XX 파트는 컬러가 fixed 컬러ì�¸ì§€ 확ì�¸í•˜ëŠ”ë�° 사용하며 ì�´ê²½ìš° XX는 00ì�´ì–´ì•¼ í•˜ê³ , 시스템 컬러ì�˜ ì�¸ë�±ìФì�¸ì§€ 확ì�¸í•œë‹¤. 알파 채ë„�ì�„ 위한 공간ì�€ 예약ë�˜ì–´ì§€ì§€ 않았다.
분리� RGB 채�� TColor로 변환하기 위해서는 다�� 사용한다:RGBToColor(RedVal, GreenVal, BlueVal);
TColorì�˜ ê°�ê°�ì�˜ 채ë„�ì�„ ì–»ìœ¼ë ¤ë©´ 변수는 Red, Green ë°� Blue 함수ì�„ 사용한다:RedVal := Red(MyColor); GreenVal := Green(MyColor); BlueVal := Blue(MyColor);
### TFPColor
TFPColor는 대부분ì�˜ ë�¼ì�´ë¸ŒëŸ¬ì—�서 ì�¼ë°˜ì �ì�¸ AARRGGBB í�¬ë§·ì�„ 사용한다.
## LCL 없� 그리기
LCL ì—†ì�´ 그릴 수 있다. 예를 들어 웹서버ì—�서 ë�Œì•„가는 프로그램ì�´ ë§Œë“ ê·¸ëž˜í”½ì�€ ì™„ì „í•œ 비주얼 ë�¼ì�´ë¸ŒëŸ¬ë¦¬ê°€ 없어ë�„ ë�™ìž‘해야 한다. ì�´ë¥¼ 위해 FPImage(별명ì�€ fcl-image)를 ì‚¬ìš©í• ìˆ˜ 있다, ì�´ëŠ” 파스칼로 작성ë�œ 매우 ì�¼ë°˜ì �ì�¸ ì�´ë¯¸ì§€ì�´ë©° 드로잉 ë�¼ì�´ë¸ŒëŸ¬ë¦¬ì�´ë‹¤. 사실 LCLì�€ ì—시 FPImage를 ì‚¬ìš©í•˜ê³ ìœ„ì ¯ì…‹(winapi, gtk, carbon, ...)ì�˜ 호출ì�„ 통해 드로임 함수를 구현한다.
여기ì—� 200x100 ì�´ë¯¸ì§€ë¥¼ ìƒ�ì„±í•˜ê³ ë°±ìƒ‰ìœ¼ë¡œ ë°°ê²½ì�„ ì¹ í•˜ë©° 몇몇 í…�스트를 ì“°ê³ .png로 ì €ìž¥í•˜ëŠ” 방법ì—� 관한 예가 있다:program fontdraw;
{$mode objfpc}{$H+}uses
Classes, SysUtils, FPimage, FPImgCanv, ftfont, FPWritePNG, FPCanvas;procedure TestFPImgFont;
var
Img: TFPMemoryImage;
Writer: TFPWriterPNG;
ms: TMemoryStream;
ImgCanvas: TFPImageCanvas;
fs: TFileStream;
AFont: TFreeTypeFont;
begin
Img:=nil;
ImgCanvas:=nil;
Writer:=nil;
ms:=nil;
fs:=nil;
AFont:=nil;
try
// 프리타입 í�°íЏ ë§¤ë‹ˆì € 초기화
ftfont.InitEngine;
FontMgr.SearchPath:='/usr/share/fonts/truetype/ttf-dejavu/';
AFont:=TFreeTypeFont.Create;// í� 200, 높ì�´ 100ì�˜ ì�´ë¯¸ì§€ ìƒ�성
Img:=TFPMemoryImage.Create(200,100);
Img.UsePalette:=false;
// 드로잉 �작� 통해 캔버스 �성
ImgCanvas:=TFPImageCanvas.create(Img);// 하얀 ë°°ê²½ ì¹ í•¨
ImgCanvas.Brush.FPColor:=colWhite;
ImgCanvas.Brush.Style:=bsSolid;
ImgCanvas.Rectangle(0,0,Img.Width,Img.Height);// �스트 그리기
ImgCanvas.Font:=AFont;
ImgCanvas.Font.Name:='DejaVuSans';
ImgCanvas.Font.Size:=20;
ImgCanvas.TextOut(10,30,'Test');// 메모리 스트림� png로 �미지 쓰기
Writer:=TFPWriterPNG.create;
ms:=TMemoryStream.Create;
writer.ImageWrite(ms,Img);
// 메모리 스트림� 파�� 쓰기
ms.Position:=0;
fs:=TFileStream.Create('testfont.png',fmCreate);
fs.CopyFrom(ms,ms.Size);finally
AFont.Free;
ms.Free;
Writer.Free;
ImgCanvas.Free;
Img.Free;
fs.Free;
end;end;begin
TestFPImgFont;
end.
* [[Free Pascal Tutorial|파스칼 íŠœí† ë¦¬ì–¼]] \- [Tao Yue's](<http://www.taoyue.com/>) [Pascal Tutorial](<http://www.taoyue.com/tutorials/pascal/>)
* [[Free Pascal videos|Free Pascal video tutorials]]
---
*From the Free Pascal wiki, page "Developing with Graphics/ko", as the Internet Archive kept it on 2025-02-19, last changed on 2020-02-09. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*