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
Svg "Fill: Url(#....)" Behaving Strangely in Firefox
CSS Percentage Width and Text-Overflow in a Table Cell
Twitter Bootstrap 3 How to Activate Navbar-Collapse on Small Devices
How to Define a Less Mixin to Generate a Transition-Property with a Variable Number of Parameters
CSS - Circle with Margin on Border
@Font Face Choppy Font in Chrome
Use CSS to Hide Contents on Print
How to Get Cross Browser Compatibility in Print on Page from All Browsers
Best Way to Use Media Queries for Mobile Designs
How to Change Bootstrap 3's Glyphicons to White
Calc() Function Inside Another Calc() in CSS
Converting Between Physical Pixels and CSS Pixels
Bootstrap 4 Form Input with Icon for Validation
@Import or <Link> for Importing Stylesheets
How Do CSS Sprites Speed Up a Web Site
Chrome Position:Fixed Inside Position:Absolute Breaking with Iframe/Video