๋ฐ˜์‘ํ˜•

์ง€๋‚œ ํฌ์ŠคํŒ…์— ์ด์–ด GDI+, ๋”๋ธ” ๋ฒ„ํผ๋ง ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ ๊ทธ๋ฆด ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

[MFC] ๊ทธ๋ฆผํŒ(mspaint) ๋งŒ๋“ค๊ธฐ ํ”„๋กœ์ ํŠธ #1

[MFC] ๊ทธ๋ฆผํŒ(mspaint) ๋งŒ๋“ค๊ธฐ ํ”„๋กœ์ ํŠธ #2

๋„ํ˜•์„ ์–ด๋–ป๊ฒŒ ๊ทธ๋ฆด ๊ฒƒ์ธ๊ฐ€

์‚ฌ์‹ค ์ฒ˜์Œ์—๋Š” vector๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ IFigure๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ๊ทธ๋ฆฌ๋„๋ก ๊ตฌํ˜„ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด, ์—ฌ๋Ÿฌ ๋„ํ˜•์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ทธ๋ฆฌ๊ณ  ๋‚œ ํ›„ ํŠน์ • ๋„ํ˜• ํŽธ์ง‘์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ๋˜๋Š” ์‚ญ์ œ๋„ ๊ฐ€๋Šฅํ•˜๊ฒ ์ฃ ? ๋’ค๋กœ ๋˜๋Œ๋ฆฌ๊ธฐ ์ž‘์—…๋„ ๊ฐ€๋Šฅํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ CropBox๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„ํ˜•์ด ํŽธ์ง‘๋œ ๊ฒฝ์šฐ, vector์— ์žˆ๋Š” ๋„ํ˜•์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ฒŒ ๋˜๋ฉด ์›๋ณต ๋˜๊ฒ ์ฃ ?

๊ทธ๋ž˜์„œ ๋ณธ๋ฌธ์˜ ๊ทธ๋ฆผํŒ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” vector๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๊ทธ๋•Œ๊ทธ๋•Œ ์ถ”๊ฐ€ํ•œ ๋„ํ˜•์„ ์ด๋ฏธ์ง€์— ๋ง ๊ทธ๋ฆฌ๊ธฐ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Œ๋ฆฌ๊ธฐ๋Š” ๊ธฐ๋Šฅ์€ ์•ˆ๋˜์ง€๋งŒ CropBox ์ง€์ • ํ›„ ํŽธ์ง‘ํ•˜๋ฉด ๊ทธ๋Œ€๋กœ ์œ ์ง€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก , vector๋กœ ๊ตฌํ˜„ํ•˜๊ณ  CropBox๋กœ ํŽธ์ง‘๋œ ๊ฒฝ์šฐ์˜ Canvas๋„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ณ ... ์ฝ”๋“œ๋ฅผ ๋ณด์™„ํ•˜๋ฉด Windows ๊ทธ๋ฆผํŒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

//์ธ๋ฑ์Šค ๋ณ„ ์„ ํƒ์„ ์œ„ํ•œ ๊ฒฝ์šฐ.
std::vector<std::shared_ptr<Figure::IFigure>> m_figures;

//์ผํšŒ์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ.
std::shared_ptr<Figure::IFigure> m_figure;

GDI ๋˜๋Š” GDI+

์‚ฌ์‹ค GDI๋“  GDI+๋“  ๋ฌด์—‡์„ ์‚ฌ์šฉํ•˜๋Š”์ง€๋Š” ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. ๊ทธ์ € GDI+์— Drawing ๊ด€๋ จ ์˜ˆ์œ ํšจ๊ณผ๊ฐ€ ๋” ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. GDI+๋Š” ๋ถˆํˆฌ๋ช… ํšจ๊ณผ๋ผ๋“ ๊ฐ€ Smoothing, Anti-Aliasing ๋“ฑ์˜ ๊ฐ์ข… ํšจ๊ณผ๋ฅผ ์ง€์›ํ•˜๊ณ , ๊ฐœ์ธ์ ์œผ๋ก  GDI+ ์‚ฌ์šฉ ๋ฒ•์ด ๋” ํŽธํ•˜๋”๊ตฐ์š”.

๋”๋ธ” ๋ฒ„ํผ๋ง(Double Buffering)

๋”๋ธ” ๋ฒ„ํผ๋ง์ด ๋ฌด์—‡์ธ์ง€๋Š” ์•Œ๊ณ  ๊ณ„์‹ ๊ฐ€์š”? ์•„๋ž˜์˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

[GDI] ๋”๋ธ” ๋ฒ„ํผ๋ง(Double Buffering) ์†Œ๊ฐœ

[GDI+] ๋”๋ธ” ๋ฒ„ํผ๋ง(Double Buffering) ์‚ฌ์šฉํ•˜๊ธฐ

์ฆ‰, ๊นœ๋นก์ž„ ํ˜„์ƒ(Flicker) ๋•Œ๋ฌธ์— ๋”๋ธ” ๋ฒ„ํผ๋ง์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ์ฑ„์šฐ๊ณ , ๊ทธ ์œ„์— ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋ฆฌ๊ณ (Drawing), ๊ทธ ์œ„์— ๋„ํ˜•์„ ๊ทธ๋ฆฌ๋Š” ๋™์ž‘์ด ๋งˆ์šฐ์Šค Drag ์›€์ง์ž„์— ๋”ฐ๋ผ ๊ณ„์†ํ•ด์„œ ๋ฐ˜๋ณต๋œ๋‹ค๋ฉด ์‹œ๊ฐ์ ์œผ๋กœ ๊นœ๋นก์ด๋“ฏ์ด ๋‚˜ํƒ€๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜์˜ ์บ”๋ฒ„์Šค(Canvas)์— ๋ฐฐ๊ฒฝ์„ ๊ทธ๋ฆฌ๊ณ , ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๊ณ , ๋„ํ˜•์„ ๊ทธ๋ฆฌ๋Š” ์ˆœ์œผ๋กœ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Draw() ํ•จ์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

void CExamPaintDlg::OnDrawImage()
{
	//View ์˜์—ญ์˜ DC๋ฅผ ์–ป๋Š”๋‹ค.
	CPaintDC dc(this);

	//์–ป์–ด์ง„ DC์˜ Graphics๋ฅผ ์–ป๋Š”๋‹ค.
	Gdiplus::Graphics mainG(dc.GetSafeHdc()); 
    
	//ํ˜„์žฌ ๊ทธ๋ฆฌ๋Š” Canvas์˜ Graphics๋ฅผ ์–ป๋Š”๋‹ค.
	Gdiplus::Graphics memG(m_canvasDuringDraw.get());
    
	//ํ˜„์žฌ ๊ทธ๋ฆฌ๋Š” Canvas์— ๋งˆ์ง€๋ง‰์— ๋ฐฑ์—…ํ•œ Canvas๋ฅผ ๊ทธ๋ฆฐ๋‹ค.
	memG.DrawImage(m_canvasAfterDrawing.get(), 0, 0, m_canvasAfterDrawing->GetWidth(), m_canvasAfterDrawing->GetHeight());
	
	//๋„ํ˜•์ด ์กด์žฌํ•˜๋ฉด ํ˜„์žฌ Graphics์— ๊ทธ๋ฆฐ๋‹ค.
	if (m_figure != nullptr)
		m_figure->Draw(&memG);
	
	//View DC์˜ Graphics์— ํ˜„์žฌ ๊ทธ๋ ค์ง„ Canvas๋ฅผ ๊ทธ๋ฆฐ๋‹ค(์ตœ์ข…๋ณธ์„ ๊ทธ๋ฆฐ๋‹ค).
	mainG.DrawImage(m_canvasDuringDraw.get(), 0, 0);
}

๋งŒ์•ฝ, ์œ„ ์ฝ”๋“œ์—์„œ mainG์—๋งŒ Draw ํ•œ๋‹ค๋ฉด ์ด๋Š” ๋”๋ธ” ๋ฒ„ํผ๋ง์ด ์•„๋‹Œ ๋ง ๊ทธ๋ฆฌ๊ธฐ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๊นœ๋นก์ž„ ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚˜๊ฒ ์ฃ ?

๋ฐฑ์—…ํ•  ์บ”๋ฒ„์Šค(Canvas)์™€ ๊ทธ๋ ค์งˆ ์บ”๋ฒ„์Šค

๋™์ผํ•œ ์บ”๋ฒ„์Šค์— ๊ทธ๋ฆด ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

์•ž์—์„œ ์–ธ๊ธ‰๋œ ์ฝ”๋“œ์— m_canvasDuringDraw์™€ m_canvasAfterDrawing์ด ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„์žฌ ๊ทธ๋ ค์ง€๊ณ  ์žˆ๋Š” ์บ”๋ฒ„์Šค(m_canvasDuringDraw)์™€ ๋งˆ์ง€๋ง‰์— ๊ทธ๋ ค์ง„ ์บ”๋ฒ„์Šค(m_canvasAfterDrawing, ๋ฐฑ์—…ํ•  ์บ”๋ฒ„์Šค)๋ฅผ ์˜๋ฏธํ•˜๋Š”๋ฐ์š”. ๋˜‘๊ฐ™์€ ์บ”๋ฒ„์Šค์— ์—ฐ๋‹ฌ์•„์„œ ๊ณ„์† ๊ทธ๋ฆฌ๊ฒŒ ๋˜๋ฉด, ๋„ํ˜•์˜ ์›€์ง์ž„์ด ํ”์ ์œผ๋กœ ๋‚จ์•„ ์œ„์™€ ๊ฐ™์€ ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์™€ ์—ฐ๋™ํ•˜์—ฌ, ๊ทธ๋ฆฌ๋Š” ๋™์ž‘์ด ์™„๋ฃŒ๋˜๋ฉด ๊ทธ๋ ค์ง„ ์บ”๋ฒ„์Šค๋ฅผ ๋ฐฑ์—…ํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์™ผ์ชฝ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ์ด ํด๋ฆญ๋  ๋•Œ, ํ˜„์žฌ๊นŒ์ง€ ๊ทธ๋ ค์ง„ ๊ทธ๋ฆผ์„ ๋ฐฑ์—… ์บ”๋ฒ„์Šค์— ๋ณด๊ด€ํ•˜๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

void CExamPaintDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	//...

	//๋งˆ์ง€๋ง‰ ์บ”๋ฒ„์Šค๋ฅผ ๊ฐ€์ ธ์™€์„œ
	Gdiplus::Graphics memG(m_canvasAfterDrawing.get());
	//ํ˜„์žฌ ์บ”๋ฒ„์Šค๋ฅผ ๋ง ๊ทธ๋ฆฐ๋‹ค.
	memG.DrawImage(m_canvasDuringDraw.get(), 0, 0, m_canvasDuringDraw->GetWidth(), m_canvasDuringDraw->GetHeight());
	//...
}

์ด์ œ ๊ฑฐ์˜ ๋‹ค ์™”์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” MFC์—์„œ ๊ฐ์ข… ์ด๋ฒคํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ์—ฐ๋™ํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•