성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>WPF - Line 요소를 Canvas에 위치시켰을 때 흐림(blur) 현상</h1> <p> WPF 관련 업무에서 멀어지다 보니, 이젠 아래의 글을 어떻게 작성했는지 조차 기억이 가물가물합니다. ^^;<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > WPF/Silverlight의 그래픽 단위와 Anti-aliasing 처리를 이해하자 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1281'>http://www.sysnet.pe.kr/2/0/1281</a> </pre> <br /> 그런데, 아래와 같은 질문이 들어왔군요. (그래서 이전에 쓴 제 글을 다시 읽어봤습니다. ^^)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 안녕하세요. SnapsToDevicePixels 질문입니다. ; <a target='tab' href='http://www.sysnet.pe.kr/3/0/4775'>http://www.sysnet.pe.kr/3/0/4775</a> </pre> <br /> 어쨌든, 위의 질문을 간단하게 재현해 보면 이렇습니다. 다음과 같은 XAML을 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Window x:Class="SnapToPixelTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" x:Name="xWindow" Height="350" Width="300"> <Grid x:Name="xGrid"> <Canvas x:Name="xCanvas"> <Line <span style='color: blue; font-weight: bold'>Canvas.Top="10" Canvas.Left="10"</span> X2="50" Y2="0" Stroke="Black" StrokeThickness="1" <span style='color: blue; font-weight: bold'>SnapsToDevicePixels="True"</span> /> </Canvas> </Grid> </Window> </pre> <br /> 실행해 보면, 선이 뚜렷하게 안 보이고 약간 굵으면서 흐린 부분이 보입니다. 확대해 보면 2pixel 굵기로 위는 흐리고 아래는 뚜렷합니다.<br /> <br /> [그림 1: SnapsToDevicePixels == True인 경우, 상단 1pixel 흐리고 하단 1pixel 뚜렷함]<br /> <img alt='wpf_snap_1.png' src='/SysWebRes/bbs/wpf_snap_1.png' /><br /> <br /> "<a target='tab' href='http://www.sysnet.pe.kr/2/0/1281'>WPF/Silverlight의 그래픽 단위와 Anti-aliasing 처리를 이해하자</a>" 글의 내용대로라면, 위의 코드는 소수점을 포함하는 그 어떠한 연산도 없기 때문에 흐리게 나와야 할 이유가 없습니다. 게다가 런타임 시에 위치를 보정해 주는 SnapsToDevicePixels 옵션까지 True로 설정했는데 흐리게 나오다니요????!!!!! (사실 이건 이유를 잘 모르겠습니다.)<br /> <br /> 물론, SnapsToDevicePixels 옵션을 제거하면 상황이 더 안 좋게 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas"> <Line Canvas.Top="10" Canvas.Left="10" X2="50" Y2="0" Stroke="Black" StrokeThickness="1" /> </Canvas> </pre> <br /> [그림 2: SnapsToDevicePixels == False인 경우, 2pixel 모두 흐림]<br /> <img alt='wpf_snap_2.png' src='/SysWebRes/bbs/wpf_snap_2.png' /><br /> <br /> 그렇긴 한데, 저 결과는 "<a target='tab' href='http://www.sysnet.pe.kr/2/0/1281'>WPF/Silverlight의 그래픽 단위와 Anti-aliasing 처리를 이해하자</a>" 글에 나온 대로여서 이상할 것이 없습니다. <br /> <br /> 따라서, 위의 상황에서 1pixel짜리 선을 뚜렷하게 표현하려면 정수(integer) 단위의 물리 Pixel을 맞춰주면 됩니다. 이를 위해 0.5를 보정하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas"> <Line <span style='color: blue; font-weight: bold'>Canvas.Top="9.5"</span> Canvas.Left="10" X2="50" Y2="0" Stroke="Black" StrokeThickness="1" /> </Canvas> </pre> <br /> 이렇게 잘 나옵니다.<br /> <br /> [그림 3: 뚜렷한 1pixel]<br /> <img alt='wpf_snap_3.png' src='/SysWebRes/bbs/wpf_snap_3.png' /><br /> <br /> 재미있는 것은 위의 코드에 SnapsToDevicePixels 옵션을 주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas"> <Line Canvas.Top="9.5" Canvas.Left="10" X2="50" Y2="0" Stroke="Black" StrokeThickness="1" <span style='color: blue; font-weight: bold'>SnapsToDevicePixels="True"</span> /> </Canvas> </pre> <br /> 다시 흐려집니다.<br /> <br /> [그림 4: 흐린 1pixel]<br /> <img alt='wpf_snap_4.png' src='/SysWebRes/bbs/wpf_snap_4.png' /><br /> <br /> 그런데, 더 재미있는 것이 있습니다. Canvas.Top, Canvas.Left를 지정하지 않고 Line 자체의 X1, Y1과 함께 SnapsToDevicePixels 옵션을 이렇게 지정해도 뚜렷한 1pixel을 그릴 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas"> <Line <span style='color: blue; font-weight: bold'>X1="10" Y1="10"</span> X2="50" Y2="10" Stroke="Black" StrokeThickness="1" <span style='color: blue; font-weight: bold'>SnapsToDevicePixels="True"</span> /> </Canvas> </pre> <br /> 하지만 여기다 UseLayoutRounding="True"를 주면 오히려,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas" <span style='color: blue; font-weight: bold'>UseLayoutRounding="True"</span> > <Line X1="10" Y1="10" X2="50" Y2="10" Stroke="Black" StrokeThickness="1" SnapsToDevicePixels="True" /> </Canvas> </pre> <br /> "[그림 2: SnapsToDevicePixels == False인 경우, 2pixel 모두 흐림]"처럼 2pixel 흐린 선이 나옵니다. 일단, UseLayoutRounding이 사용되면 이제 다시 소수점 처리로 들어가야 합니다. (아래에서는 SnapsToDevicePixels 유무에 상관없습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Canvas x:Name="xCanvas" UseLayoutRounding="True"> <Line X1="10" Y1="10.5" X2="50" Y2="10.5" Stroke="Black" StrokeThickness="1" /> </Canvas> </pre> <br /> 위의 결과는 다시 "[그림 3: 뚜렷한 1pixel]"처럼 나옵니다. 그나저나... 저런 규칙 아닌 규칙들을 다 알아야 한다는 것이 좀 우습군요. <br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1084&boardid=331301885'>첨부파일은 질문 글의 소스 코드를 1pixel 뚜렷한 걸로 바꾼 것</a>입니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 여기서 힘든 부분이 있습니다. UseLayoutRounding은 하위 요소로 상속되기 때문에 Canvas를 사용하는 상단 중에 하나라도 설정되어 있으면 저렇게 소수점 처리를 해야 합니다. 휴~~~ 좀 좋은 방법 없을까요? 저도 이젠 피곤해지는군요. ^^;<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1995
(왼쪽의 숫자를 입력해야 합니다.)