Web Forms 응용 프로그램에서 이미지의 특정 부분에 텍스트를 렌더링하려고합니다. 텍스트는 사용자가 입력하므로 글꼴 상자를 테두리 상자에 맞도록 글꼴 크기를 변경하고 싶습니다.잘못된 크기 계산을하는 Graphics.MeasureCharacterRanges
개념 증명 구현에서이 작업을 수행하는 코드가 있지만 디자이너의 자산에 비해 더 큰 크기의 애셋을 사용하려고 노력 중입니다. 이상한 결과가 나타납니다. 다음과 같이
나는 크기 계산을 실행 해요 :
StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Near;
fmt.FormatFlags = StringFormatFlags.NoClip;
fmt.Trimming = StringTrimming.None;
int size = __startingSize;
Font font = __fonts.GetFontBySize(size);
while (GetStringBounds(text, font, fmt).IsLargerThan(__textBoundingBox))
{
context.Trace.Write("MyHandler.ProcessRequest",
"Decrementing font size to " + size + ", as size is "
+ GetStringBounds(text, font, fmt).Size()
+ " and limit is " + __textBoundingBox.Size());
size--;
if (size < __minimumSize)
{
break;
}
font = __fonts.GetFontBySize(size);
}
context.Trace.Write("MyHandler.ProcessRequest", "Writing " + text + " in "
+ font.FontFamily.Name + " at " + font.SizeInPoints + "pt, size is "
+ GetStringBounds(text, font, fmt).Size()
+ " and limit is " + __textBoundingBox.Size());
그때 내가 파일 시스템에서 당겨있어 이미지 위에 텍스트를 렌더링하기 위해 다음 줄을 사용
:
g.DrawString(text, font, __brush, __textBoundingBox, fmt);
:
__fonts
는 ,369
PrivateFontCollection.GetFontBySize
는FontFamily
RectangleF __textBoundingBox = new RectangleF(150, 110, 212, 64);
int __minimumSize = 8;
int __startingSize = 48;
Brush __brush = Brushes.White;
int size
는- 갖는다
SmoothingMode.AntiAlias
Graphics g
및TextRenderingHint.AntiAlias
는 설정하는 루프 내 48 아웃 시작 및 감소 리턴 확장 방법
context
가System.Web.HttpContext
이다
PrivateFontCollection
입니다 1,363,210
(이것이 IHttpHandler
의 ProcessRequest
방법에서 발췌) 다른 방법은 :
private static RectangleF GetStringBounds(string text, Font font,
StringFormat fmt)
{
CharacterRange[] range = { new CharacterRange(0, text.Length) };
StringFormat myFormat = fmt.Clone() as StringFormat;
myFormat.SetMeasurableCharacterRanges(range);
using (Graphics g = Graphics.FromImage(new Bitmap(
(int) __textBoundingBox.Width - 1,
(int) __textBoundingBox.Height - 1)))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
Region[] regions = g.MeasureCharacterRanges(text, font,
__textBoundingBox, myFormat);
return regions[0].GetBounds(g);
}
}
public static string Size(this RectangleF rect)
{
return rect.Width + "×" + rect.Height;
}
public static bool IsLargerThan(this RectangleF a, RectangleF b)
{
return (a.Width > b.Width) || (a.Height > b.Height);
}
는 이제 두 가지 문제점이있다.
첫 번째로 가끔은 단어 내에 줄 바꿈을 삽입하여 줄 바꿈을 요구합니다. 다만 줄 바꿈이 실패 할 경우에만 while 루프가 다시 감소하게됩니다. 나는 왜 그것이 단어 내에 랩핑해서는 안되는 지 상자 안에 들어 맞다고 생각하는 이유를 알 수 없다. 이 동작은 사용 된 문자 집합과 관계없이 표시됩니다 (키릴 문자, 그리스어, 그루지야 어 및 아르메니아어와 같이 유니 코드 범위의 다른 부분은 물론 라틴 알파벳으로도 알 수 있습니다). Graphics.MeasureCharacterRanges
을 공백 문자 (또는 하이픈)에서 단어 줄 바꿈 만 사용하도록 설정해야하는 몇 가지 설정이 있습니까? 이 첫 번째 문제는 post 2499067과 같습니다.
둘째, 새 이미지와 글꼴 크기까지 확대 할 때 Graphics.MeasureCharacterRanges
을 사용하면 큰 차이가 있습니다. RectangleF
내에서 그림을 볼 때 이미지의 시각적 영역에 해당하므로 필요한 경우보다 텍스트가 더 많이 감소하는 것을 쉽게 볼 수 있습니다. 그러나 일부 텍스트를 전달할 때 GetBounds
호출은 나에게 실제로 걸리는 높이의 두 배를주고 있습니다.
시도 및 오류를 사용하여 __minimumSize
에서 while 루프를 종료하도록 설정하면 경계 상자 내에 24pt 텍스트가 들어가는 것을 볼 수 있습니다. 그러나 Graphics.MeasureCharacterRanges
은 한 번 이미지에 렌더링 된 해당 텍스트의 높이가, 122px입니다 (테두리 상자의 크기가 64px이고 상자 안에 들어있는 경우). 실제로 while 루프는 18pt로 반복되고 어떤 점에서는 Graphics.MeasureCharacterRanges
이 맞는 값을 반환합니다.
다음 추적 로그 발취된다 같이
24 폰트 크기를 감소시키는 크기는 191 × 117이므로, 크기가 193 × 122이고 한계는 212 × 64
가 23 폰트 크기를 감소시키는대로 크기는 200 × 75이고, 크기는 192 × 71이므로 한도는 212 × 64
크리먼트 폰트 크기가 21이고, 한계 212 × 64
크리먼트 폰트 같이 리미트는 212 × 64
가 22 폰트 크기를 감소시키는 것이다 크기는 20 x 198 크기는 198 x 68이고 제한은 212 x 64
감소 19 menting 폰트 크기, 크기는 185 × 65이고 한계는 212 × 64
18pt에서 DIN-블랙 페네호르 작성 오프 헤셀링크, 크기는 178 × 61이고 한계는 212 × 64
왜이기 때문에 Graphics.MeasureCharacterRanges
이 나에게 잘못된 결과를 주는가? 루프가 21pt 주위에 멈추었을 때 글꼴의 선 높이를 이해할 수있었습니다 (결과가 스크린 샷으로 표시되고 Paint.Net에서 측정되는 경우 시각적으로 적합합니다).하지만 수행해야 할 것보다 훨씬 더 진행되고 있습니다. 왜냐하면 솔직히 잘못된 결과를 돌려주고 있기 때문입니다.
내가 잠시 본 문서 중 가장 잘 나온 질문 중 하나입니다. – SouthShoreAK