Моя программа является своего рода копией MS Paint и Pickpick. и одна из функций — растеризация выбранного объекта, такого как текстовый блок или фигура.
Что касается выбираемого объекта, для изменения размера и перемещения с помощью декоративного элемента у него есть 1 ContentControl, который содержит 1 текстовый блок + 1 фигуру.
ContentControl (able to resize, rotate, move)
└─> Textblock (bold, italic, V-align, H-align, word wrap...)
└─> Shape (can be a triangle, rectangle etc...)
Было несложно преобразовать форму для рисования в контексте рисования вместо рендеринга на Canvas.
var SH = CC.GetShape();
var TB = CC.GetTextBlock();
var visual = new DrawingVisual();
Geometry geo = null;
System.Windows.Media.Pen pen = null;
System.Windows.Media.Brush brush = null;
if (SH != null)
{
geo = SH.RenderedGeometry; // shape to geo
if (geo == null)
return;
pen = new System.Windows.Media.Pen(SH.Stroke, SH.StrokeThickness);
brush = SH.Fill;
}
using (var dc = visual.RenderOpen())
{
// Draw the background first
dc.DrawImage(first, new Rect(0, 0, first.Width, first.Height));
dc.PushTransform(new TranslateTransform(left, top));
// Draw the shape
if (SH != null && geo != null)
dc.DrawGeometry(brush, pen, geo);
}
Но при рисовании Textblock с контекстом рисования я указал ссылку ниже для расчета положения Textblock Вертикальное выравнивание с DrawingContext.DrawText
, но проблема заключается в том, что Textblock имеет многострочный или словесный перенос.
скриншот моей программы
if (TB.Text.Equals(string.Empty) == false)
{
var typeface = new Typeface(CC.txtSetting.fontFamily,
CC.txtSetting.fontStyle,
CC.txtSetting.fontWeight,
FontStretches.Normal);
var formattedText = new FormattedText(TB.Text
, CultureInfo.CurrentCulture
, FlowDirection.LeftToRight
, typeface
, CC.txtSetting.fontSize
, new SolidColorBrush(CC.txtSetting.fontColor));
double centerX = CC.ActualWidth / 2;
double centerY = CC.ActualHeight / 2;
double txtPositionX = 0.0f;
double txtPositionY = 0.0f;
if (TB.TextAlignment == TextAlignment.Left)
{
txtPositionX = 1.0f;
}
else if (TB.TextAlignment == TextAlignment.Center)
{
txtPositionX = centerX - formattedText.WidthIncludingTrailingWhitespace / 2;
}
else if (TB.TextAlignment == TextAlignment.Right)
{
txtPositionX = CC.Width -
formattedText.WidthIncludingTrailingWhitespace - 1.0f;
}
if (TB.VerticalAlignment == VerticalAlignment.Top)
{
txtPositionY = 1.0f;
}
else if (TB.VerticalAlignment == VerticalAlignment.Center)
{
txtPositionY = centerY - formattedText.Height / 2;
}
else if (TB.VerticalAlignment == VerticalAlignment.Bottom)
{
txtPositionY = CC.Height - formattedText.Height - 1.0f;
}
var ptLocation = new System.Windows.Point(txtPositionX, txtPositionY);
dc.DrawText(formattedText, ptLocation);
}
Кроме того, текстовый блок обернут ContentControl, поэтому в зависимости от изменения пользователем свойства текстового блока оно будет сильно различаться. Я думаю, что невозможно преобразовать каждую переменную. Итак, я думаю об альтернативных способах рисования.
- Рисуйте с помощью GDI+ вместо рисования в контексте рисования. (все еще неуверенно)
- Используйте контекст рисования, пока пользователь редактирует текст. (так что это будет то же самое до растеризации и наоборот)
- Любой способ напрямую преобразовать/захватить текстовый блок в изображение или геометрию? (это был бы лучший способ, если бы это было возможно.) Например, чтобы получить источник изображения с эффектом шейдера, мне это понравилось. так.. наверное есть способ. Как я могу получить объект источника с эффектом < /а>
Вы также можете обратиться к этой программе с http://ngwin.com/picpick
скриншот выбора
Есть идеи получше? Заранее спасибо.