Microsoft Word 같은 프로그램을 사용하다 보면 종이 뒤에 그림자가 있습니다.
다들 한 번쯤은 보셨겠죠? 그 효과를 만들어 보고자 합니다.
CodeProject에서 이와 관련된 문서를 찾았는데요~ 일단 링크를 걸었습니다.
그리고 이 작업에 사용된 이미지 파일들은 'Resources.zip'이라는 이름으로 첨부했습니다.
코드프로젝트에서 사용한 코드와 제 코드는 방식이 약간 다릅니다. 이미지만 가져와서 사용하고 코드는 그냥 제가 작성했거든요
대충 보니까 링크된 문서의 코드는 Panel을 하나 만들어서 그 안에 그림자를 그려 넣은 듯 하구요~
제가 만든 코드는 Panel의 모서리에 맞춰서 해당 Panel을 가지고 있는 Parent객체에 그려 넣은 것입니다.
하지만 작성해 놓고 보니까 비슷하더 라구요~ 아래는 코드를 적용한 예 입니다.
코드를 먼저 볼까요?
//mainPanel을 그리기 표면으로 사용하기 위해 변수지정
Graphics g = e.Graphics;
#region 그림자 그리기
//우측상단
g.DrawImage(Properties.Resources.Shadow_TopRight, editControl1.Right, editControl1.Top, 5, 5);
//우측, TextureBrush 사용
TextureBrush tb = new TextureBrush(Properties.Resources.Shadow_Right);
tb.TranslateTransform(editControl1.Right, 0); //이미지 반복 시작 위치를 설정합니다. (기본값은 (0,0) 입니다.)
g.FillRectangle(tb, editControl1.Right, editControl1.Top + 5, 5, editControl1.Height - 5);
//우측하단
g.DrawImage(Properties.Resources.Shadow_BottomRight, editControl1.Right, editControl1.Bottom, 5, 5);
//하단
tb = new TextureBrush(Properties.Resources.Shadow_Bottom);
tb.TranslateTransform(0, editControl1.Bottom); //이미지 반복 시작 위치를 설정합니다. (기본값은 (0,0) 입니다.)
g.FillRectangle(tb, editControl1.Left + 5, editControl1.Bottom, editControl1.Width - 5, 5);
//좌측 하단
g.DrawImage(Properties.Resources.Shadow_BottomLeft, editControl1.Left, editControl1.Bottom, 5, 5);
#endregion
}
코드는 주석처리 된 그대로 입니다.
editControl1 이라는 객체가 바로 흰색 컨트롤이구요, 실제로 화면을 그린 곳은 회색 컨트롤인 mainPanel입니다.
위의 코드는 바깥 패널인 mainPanel의 Paint 이벤트에 등록할 메서드 입니다.
TextureBrush를 사용한 이유?
오른쪽과 아래쪽의 코드에 DrawImage를 쓰지 않은 이유는 이미지를 심하게 늘리면 이쁘게 그림자가 안 생기기 때문이죠~
마치 Anti-Aliasing을 한 것 같이 그라데이션이 생기더라구요~
처음엔 InterpolationMode 속성을 이용해서 그 문제를 어떻게 해 볼 수 있을 것 같다고 생각했는데요 힘들더라구요~
그래서 TextureBrush를 썼습니다. 뭐 이게 가장 쉬운 방법인 것 같네요.
더불어서 TextureBrush의 TranslateTransform을 쓴 이유는...
TextureBrush의 경우 (0,0)좌표를 기준으로 Tile을 반복하기 때문이죠~ 그래서 정확한 위치에 그림자가 생기지 않을 때가 있지요..
그래서 기준 좌표를 변경해 주는 것이랍니다.
간단하죠? 이제 적절히 Invalidate()만 호출해 주면 됩니다. ^^
출처: http://www.codeproject.com/KB/miscctrl/TransparentDropShadowInCS.aspx
다들 한 번쯤은 보셨겠죠? 그 효과를 만들어 보고자 합니다.
CodeProject에서 이와 관련된 문서를 찾았는데요~ 일단 링크를 걸었습니다.
그리고 이 작업에 사용된 이미지 파일들은 'Resources.zip'이라는 이름으로 첨부했습니다.
코드프로젝트에서 사용한 코드와 제 코드는 방식이 약간 다릅니다. 이미지만 가져와서 사용하고 코드는 그냥 제가 작성했거든요
대충 보니까 링크된 문서의 코드는 Panel을 하나 만들어서 그 안에 그림자를 그려 넣은 듯 하구요~
제가 만든 코드는 Panel의 모서리에 맞춰서 해당 Panel을 가지고 있는 Parent객체에 그려 넣은 것입니다.
하지만 작성해 놓고 보니까 비슷하더 라구요~ 아래는 코드를 적용한 예 입니다.
코드를 먼저 볼까요?
private void mainPanel_Paint(object sender, PaintEventArgs e)
{//mainPanel을 그리기 표면으로 사용하기 위해 변수지정
Graphics g = e.Graphics;
#region 그림자 그리기
//우측상단
g.DrawImage(Properties.Resources.Shadow_TopRight, editControl1.Right, editControl1.Top, 5, 5);
//우측, TextureBrush 사용
TextureBrush tb = new TextureBrush(Properties.Resources.Shadow_Right);
tb.TranslateTransform(editControl1.Right, 0); //이미지 반복 시작 위치를 설정합니다. (기본값은 (0,0) 입니다.)
g.FillRectangle(tb, editControl1.Right, editControl1.Top + 5, 5, editControl1.Height - 5);
//우측하단
g.DrawImage(Properties.Resources.Shadow_BottomRight, editControl1.Right, editControl1.Bottom, 5, 5);
//하단
tb = new TextureBrush(Properties.Resources.Shadow_Bottom);
tb.TranslateTransform(0, editControl1.Bottom); //이미지 반복 시작 위치를 설정합니다. (기본값은 (0,0) 입니다.)
g.FillRectangle(tb, editControl1.Left + 5, editControl1.Bottom, editControl1.Width - 5, 5);
//좌측 하단
g.DrawImage(Properties.Resources.Shadow_BottomLeft, editControl1.Left, editControl1.Bottom, 5, 5);
#endregion
}
코드는 주석처리 된 그대로 입니다.
editControl1 이라는 객체가 바로 흰색 컨트롤이구요, 실제로 화면을 그린 곳은 회색 컨트롤인 mainPanel입니다.
위의 코드는 바깥 패널인 mainPanel의 Paint 이벤트에 등록할 메서드 입니다.
TextureBrush를 사용한 이유?
오른쪽과 아래쪽의 코드에 DrawImage를 쓰지 않은 이유는 이미지를 심하게 늘리면 이쁘게 그림자가 안 생기기 때문이죠~
마치 Anti-Aliasing을 한 것 같이 그라데이션이 생기더라구요~
처음엔 InterpolationMode 속성을 이용해서 그 문제를 어떻게 해 볼 수 있을 것 같다고 생각했는데요 힘들더라구요~
그래서 TextureBrush를 썼습니다. 뭐 이게 가장 쉬운 방법인 것 같네요.
더불어서 TextureBrush의 TranslateTransform을 쓴 이유는...
TextureBrush의 경우 (0,0)좌표를 기준으로 Tile을 반복하기 때문이죠~ 그래서 정확한 위치에 그림자가 생기지 않을 때가 있지요..
그래서 기준 좌표를 변경해 주는 것이랍니다.
간단하죠? 이제 적절히 Invalidate()만 호출해 주면 됩니다. ^^
출처: http://www.codeproject.com/KB/miscctrl/TransparentDropShadowInCS.aspx