.NET GraphicsPath.AddString으로 테두리 문자를 그리고 싶습니다.

10727 단어 Direct2DC#.NET
GraphicsPath 클래스에서 캐릭터의 패스를 추가해, 테두리를 추가하고 나서 캐릭터를 그리고 싶다.
// ※using、Dispose文は省略
var bitmap = new Bitmap(1280, 200);
// 透過
bitmap.MakeTransparent();
// BitmapからGraphicsを生成
var graphics = Graphics.FromImage(bitmap);

var stringFormat = new StringFormat();
// どんなに長くて単語の区切りが良くても改行しない
stringFormat.FormatFlags = StringFormatFlags.NoWrap;
// どんなに長くてもトリミングしない
stringFormat.Trimming = StringTrimming.None;
// ハイクオリティレンダリング
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
// アンチエイリアスをかける
graphics.SmoothingMode = SmoothingMode.HighQuality;

// GraphicsPathを生成
var gp = new GraphicsPath();

// パスに文字を追加
gp.AddString("山路を登りながら、智に働けば角が立つ。", new FontFamily("メイリオ"), 0, 46, new Point(8, 8), stringFormat);

// 縁取りをする。
graphics.DrawPath(new Pen(Color.Black, 16), gp);
// 文字を塗りつぶす。
graphics.FillPath(new SolidBrush(Color.White), gp);

// テスト用にBitmapの内容をD:\result.pngに出力
bitmap.Save("D:\\result.png", System.Drawing.Imaging.ImageFormat.Png);

주의해 주었으면 하는 것이, 테두리 하는 경우의 문자의 좌표. 문자의 패스를 추가한 좌표를 기준으로, 중앙으로부터 굵기가 바뀌어 가므로 문자의 좌표를를 테두리의 사이즈의 절반 어긋나게 할 필요가 있다. 위의 샘플에서는, 테두리의 사이즈가 16이므로 문자 자체를 new Point(8, 8) 로 하고 있다.

렌더링 결과





「치에 일하면 "뿔이"서 있다, 라고!

괜찮아! 우오! 뭔가 이상하다!

문자 자체의 패스는 정상적으로 추가되고 있지만, GraphicsPath.DrawPath 에 의한 테두리의 묘화가 파탄하고 ​​있는 것 같다.

폰트에 따라 결과가 다릅니다만(해밍이라든지 술라라든가, 둥근 계의 폰트는 괜찮다), 각장하고 있는 폰트는 이렇게 되기 쉽다…

Pen 클래스의 LineJoin 및 MiterLimit 속성



마이크로소프트의 문서의 등장이다-! Pen 클래스의 프로퍼티 Fuck하면 해결할 수 있을까, 라고 생각해 일단 이 페이지를 봐 본다. 그러면 "LineJoin - 이 Pen로 그려진 연속하는 2개의 직선의 종점의 접합 스타일을 취득 또는 설정합니다."라고 하는 아무리 그와 같은 프로퍼티를 발견했으므로 이 열거형을 변경해 본다.

LineJoin.Bevel


graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.Bevel }, gp);



대각선 테두리가 생성되는 느낌. 3DCG의 베벨 엣지와 같은 느낌이군요.

LineJoin.Miter


graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.Miter }, gp);


LineJoin.Miter = 0 그래서 이것이 기본값입니다.

LineJoin.MiterClipped


graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.MiterClipped }, gp);



이것도 LineJoin.Miter 와 거의 같은데, MiterLimit 의 값을 웃돌았을 때의 처리 방법이 다르다.
graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.Miter, MiterLimit = 2 }, gp);
graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.MiterClipped, MiterLimit = 2 }, gp);



다를 것입니다 ...... 하지만 차이가 잘 모르겠어. 포토쇼에서 감산하면 확실히 다르다는 것은 알지만.

LineJoin.Round


graphics.DrawPath(new Pen(Color.Black, 16) { LineJoin = LineJoin.Round} , gp);



개인적으로 1번 좋아. 각도하고 있지 않기 때문에 다른 것에 비해 상냥한 느낌.

요약


  • 바삭바삭한 테두리를 한다면, LineJoin.Miter 를 지정해 적절한 MiterLimit 를 지정한다.
  • 둥근 테두리를 실시하는 경우, LineJoin.Round 를 지정한다.
  • 좋은 웹페이지 즐겨찾기