Wpf Analogy for 'Em' Unit

WPF analogy for 'em' unit

AFAIK, there isn't one right now. But you can make your desire for this known here.

One alternative (and I don't know if this is possible either) would be to measure how big the desired font is, then take that as your "ems" unit, then scale using those "units" instead.

How to Specify Font Units in WPF

Just include the text pt or px in the font-size. For example,

<TextBlock Width="400" Text="">
<Run FontFamily="Microsoft Sans Serif"
FontSize="8.25 pt">Hello world!</Run>
</TextBlock>

1 pt is defined as 1/72nd of an inch; 1 px is 1/96th of an inch.

Note that unit qualifiers are only supported in WPF, not in Silverlight.

There is no equivalent to the CSS unit em, but there is a workaround.

How to increase font size in XAML?

WPF doesn't have the em font size, there alternatives in the answers to this SO

The simplist may be

<ScaleTransform ScaleX="1.2" ScaleY="1.2" /> 

Write text on top of existing image file?

Having read answers and comments here I thought you might appreciate a more comprehensive solution. Here is a little method that does the job:

public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text, Point position)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile)); // inputFile must be absolute path
DrawingVisual visual = new DrawingVisual();

using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}

RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);

BitmapEncoder encoder = null;

switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
// more encoders here
}

if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));
using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}

You would use this method with a FormattedText object and a position:

FormattedText text = new FormattedText(
"Hello",
CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface("Segeo UI"),
20,
Brushes.Red);

WriteTextToImage(
@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg",
"Desert.png",
text,
new Point(10, 10));

EDIT: If you want to draw the text horizontally and vertically aligned relative to a certain rectangle, you might replace the position parameter by that rectangle and two alignment parameters and calculate the text position like this:

public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text,
Rect textRect, HorizontalAlignment hAlign, VerticalAlignment vAlign)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile));
DrawingVisual visual = new DrawingVisual();
Point position = textRect.Location;

switch (hAlign)
{
case HorizontalAlignment.Center:
position.X += (textRect.Width - text.Width) / 2;
break;
case HorizontalAlignment.Right:
position.X += textRect.Width - text.Width;
break;
}

switch (vAlign)
{
case VerticalAlignment.Center:
position.Y += (textRect.Height - text.Height) / 2;
break;
case VerticalAlignment.Bottom:
position.Y += textRect.Height - text.Height;
break;
}

using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}

RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);

BitmapEncoder encoder = null;

switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
case ".jpg":
encoder = new JpegBitmapEncoder();
break;
}

if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));

using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}

Now you might use the method like this:

WriteTextToImage(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text,
new Rect(80, 50, 430, 200),
HorizontalAlignment.Center, VerticalAlignment.Center);

Write text on top of existing image file?

Having read answers and comments here I thought you might appreciate a more comprehensive solution. Here is a little method that does the job:

public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text, Point position)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile)); // inputFile must be absolute path
DrawingVisual visual = new DrawingVisual();

using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}

RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);

BitmapEncoder encoder = null;

switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
// more encoders here
}

if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));
using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}

You would use this method with a FormattedText object and a position:

FormattedText text = new FormattedText(
"Hello",
CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface("Segeo UI"),
20,
Brushes.Red);

WriteTextToImage(
@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg",
"Desert.png",
text,
new Point(10, 10));

EDIT: If you want to draw the text horizontally and vertically aligned relative to a certain rectangle, you might replace the position parameter by that rectangle and two alignment parameters and calculate the text position like this:

public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text,
Rect textRect, HorizontalAlignment hAlign, VerticalAlignment vAlign)
{
BitmapImage bitmap = new BitmapImage(new Uri(inputFile));
DrawingVisual visual = new DrawingVisual();
Point position = textRect.Location;

switch (hAlign)
{
case HorizontalAlignment.Center:
position.X += (textRect.Width - text.Width) / 2;
break;
case HorizontalAlignment.Right:
position.X += textRect.Width - text.Width;
break;
}

switch (vAlign)
{
case VerticalAlignment.Center:
position.Y += (textRect.Height - text.Height) / 2;
break;
case VerticalAlignment.Bottom:
position.Y += textRect.Height - text.Height;
break;
}

using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
dc.DrawText(text, position);
}

RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
bitmap.DpiX, bitmap.DpiY, PixelFormats.Default);
target.Render(visual);

BitmapEncoder encoder = null;

switch (Path.GetExtension(outputFile))
{
case ".png":
encoder = new PngBitmapEncoder();
break;
case ".jpg":
encoder = new JpegBitmapEncoder();
break;
}

if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(target));

using (FileStream outputStream = new FileStream(outputFile, FileMode.Create))
{
encoder.Save(outputStream);
}
}
}

Now you might use the method like this:

WriteTextToImage(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text,
new Rect(80, 50, 430, 200),
HorizontalAlignment.Center, VerticalAlignment.Center);


Related Topics



Leave a reply



Submit