I'm drawing a string with the folowing code:
public Image DrawString(String lString)
{
Image lImage = new Bitmap(128, 128);
Rectangle rec = new Rectangle(0, 0, lImage.Width, lImage.Height);
Graphics g = Graphics.FromImage(lImage);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
drawFormat.LineAlignment = StringAlignment.Center;
Font font = new Font("Arial", 20, FontStyle.Regular);
font = FindBestFitFont(g, lString, font, rec.Size);
g.DrawString(lString, font, Brushes.Red, rec, drawFormat);
return lImage;
}
The font looks very ugly even when i use:
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
Is there a way to make the font more smooth?
Try
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
instead.
Have you tried AntiAliasing or ClearType?
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
Related
I'm writing a simple application in c# .net core 6 and winform to "assemble" some pngs and write some text on it.
This is the Photoshop output. The Title "Baldur the invincible" is wrote in Diablo Light when i'm writing it with DrawString with Font("Diablo", 30, FontStyle.Regular)
and this is my output with the Font.
In photoshop i used Diablo Light font but in the list of system fonts, from C# code, i see just Diablo Regular.. and the result is different.
How i can set the fontweight ?
here some code:
// ---------------------------------------------------------------------------------------------- +
// All TEXT ------------------------------------------------------------------------------------- +
// ---------------------------------------------------------------------------------------------- +
{
//string familyName;
//string familyList = "";
//FontFamily[] fontFamilies;
//InstalledFontCollection installedFontCollection = new InstalledFontCollection();
//fontFamilies = installedFontCollection.Families;
Font title_font = new Font("Diablo", 30, FontStyle.Regular);
Font sub_font = new Font("Diablo", 25, FontStyle.Regular);
List<Font> list_fonts = new List<Font>();
list_fonts.Add(title_font);
list_fonts.Add(sub_font);
RectangleF tit_rect = new RectangleF(165, 70, w - (165 * 2), h);
//RectangleF sub_rect = new RectangleF(165, 82 + 30, w - (165 * 2), h);
var v = m_dict_titles["Title"];
string curr_string = tabbed_value[v].ToUpper();
float offsety = WriteTitleTextf2(map_back, 0, TL(curr_string, false), tit_rect, list_fonts, StringAlignment.Near, 5);
}
public void WriteOnBitmapf(Bitmap bmp, int col, Font font, String text, RectangleF rectf, StringAlignment st_align, float stringi = 0.0f)
{
float size = font.Size;
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
StringFormat format = new StringFormat()
{
Alignment = st_align,
LineAlignment = StringAlignment.Near
};
Brush br = col == 0 ? new SolidBrush(Color.FromArgb(0, 0, 0)) : new SolidBrush(Color.FromArgb(255, 255, 255));
g.DrawString(text, font, br, rectf, format);
g.Flush();
}
I drawing a rectangle with a dynamic number as a string on it and use it for a windows taskbar icon (overlay icon):
private void DrawOverlayIcon(string queue_count) {
Bitmap bitmap = new Bitmap(30, 30, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bitmap);
g.FillRectangle(System.Drawing.Brushes.White, 0, 0, 30, 30);
Rectangle r = new Rectangle(0, 0, 30, 30);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center; // horizontal
sf.LineAlignment = StringAlignment.Center; // vertikal
Font f = new Font("Arial", 14, System.Drawing.FontStyle.Bold);
g.DrawString(queue_count, f, System.Drawing.Brushes.Black, r, sf);
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
_icon_overlay = wpfBitmap;
So far so good. But when a user set up the windows zoom function to maybe 120% or 150% the number becomes so large that it is only displayed as one digit.
Can anyone help?
Thanks a lot.
I have never worked with drawing before and im having a little issue. I cant seem to get the output of this code to work.
The file is saving but it is not drawing on the text. Can anyone see what i may have done wrong?
EDIT: A silly mistake - the backgrond of the image was white (and the brush colour was!). The text is not centered however as i would have expected. Any ideas why SO? :)
EDIT: Image is below.
Thanks
Bitmap myBitmap = new Bitmap(#"C:\Users\Scott\desktop\blank.bmp");
Graphics g = Graphics.FromImage(myBitmap);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("My\nText",
new Font("Tahoma", 20),
Brushes.White,
new PointF(0, 0));
StringFormat strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
g.DrawString("My\nText",
new Font("Tahoma", 20), Brushes.White,
new RectangleF(0, 0, 500, 500),
strFormat);
myBitmap.Save(#"C:\Users\Scott\desktop\blank1.bmp");
I am sure you might be looking for this.
rectf = new RectangleF(655, 460, 535, 90); //rectf for My Text
using(Graphics g = Graphics.FromImage(myBitmap))
{
//g.DrawRectangle(new Pen(Color.Red, 2), 655, 460, 535, 90);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString("My\nText", new System.Drawing.Font("Tahoma", 32, FontStyle.Bold), Brushes.Black, rectf, sf);
}
//g.DrawRectangle(new Pen(Color.Red, 2), 655, 460, 535, 90); Line is used to show where your text will be written. So before you actually make your make your text You can see where this rectanlge will be created on the image. If you want the center of the image you can find the height and width and divide that by 2 to find the center of the image and than can plot the rectangle parameters accordingly.
I'm attempting to draw some centered text inside of a custom panel control. I'm able to create the text path using GraphicsPath.AddString and draw the text using Graphics.FillPath. Here's the code I'm using (it resides inside the custom panel control).
public void ApplyCenteredTextMessage(string message, FontStyle fontStyle)
{
using (Font messageFont = new Font("Arial", 36, fontStyle, GraphicsUnit.Point))
{
using (StringFormat stringFormat = new StringFormat())
{
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
using (Graphics graphics = this.CreateGraphics())
{
using (Font adjustedMessageFont = GetAdjustedFont(graphics, message, messageFont, this.Bounds, 160, 10))
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddString(message, adjustedMessageFont.FontFamily, (int) fontStyle, (graphics.DpiY * adjustedMessageFont.Size) / 72, Point.Empty, stringFormat);
RectangleF graphicsPathBounds = path.GetBounds();
PointF[] targetPoints = { new PointF(0, 0), new PointF(ClientSize.Width, 0), new PointF(0, ClientSize.Height) };
var translate = new Matrix(graphicsPathBounds, targetPoints);
path.Transform(translate);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.FillPath(Brushes.LawnGreen, path);
}
}
}
}
}
}
private Font GetAdjustedFont(Graphics graphicRef, string graphicString, Font originalFont, RectangleF container, int maxFontSize, int minFontSize)
{
Font testFont = null;
// We utilize MeasureString which we get via a control instance
for (int adjustedSize = maxFontSize; adjustedSize >= minFontSize; adjustedSize--)
{
testFont = new Font(originalFont.Name, adjustedSize, originalFont.Style);
// Test the string with the new size
SizeF adjustedSizeNew = graphicRef.MeasureString(graphicString, testFont);
if (container.Width > Convert.ToInt32(adjustedSizeNew.Width) && container.Height > Convert.ToInt32(adjustedSizeNew.Height))
{
// Good font, return it
return testFont;
}
}
return testFont;
}
The result is this
After the graphics.FillPath in the above code I try to use the GraphicsPath path with the IsVisible method to detect if any of the black squares intersect with the drawn text, but the results I get from that have the text in a completely different location than the above result in the image. I can't figure out where the difference, or stretch is coming from.
path.IsVisible result
I have the function below to generate a sample logo. What I want to do is to return a transparent png or gif instead of a white background.
How can I do that?
private Bitmap CreateLogo(string subdomain)
{
Bitmap objBmpImage = new Bitmap(1, 1);
int intWidth = 0;
int intHeight = 0;
Font objFont = new Font(
"Arial",
13,
System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Pixel);
Graphics objGraphics = Graphics.FromImage(objBmpImage);
intWidth = (int)objGraphics.MeasureString(subdomain, objFont).Width;
intHeight = (int)objGraphics.MeasureString(subdomain, objFont).Height;
objBmpImage = new Bitmap(objBmpImage, new Size(intWidth, intHeight));
objGraphics = Graphics.FromImage(objBmpImage);
objGraphics.Clear(Color.White);
objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
objGraphics.DrawString(
subdomain, objFont,
new SolidBrush(Color.FromArgb(102, 102, 102)), 0, 0);
objGraphics.Flush();
return (objBmpImage);
}
Here is the end result:
context.Response.ContentType = "image/png";
using (MemoryStream memStream = new MemoryStream())
{
CreateLogo(_subdname).Save(memStream, ImageFormat.Png);
memStream.WriteTo(context.Response.OutputStream);
}
In the CreateLogo function:
objGraphics.Clear(Color.White) was changed to objGraphics.Clear(Color.Transparent)
new SolidBrush(Color.FromArgb(102, 102, 102)) changed to new SolidBrush(Color.FromArgb(255, 255, 255))
You can do something like this:
Bitmap bmp = new Bitmap(300, 300);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.Transparent);
g.FillRectangle(Brushes.Red, 100, 100, 100, 100);
g.Flush();
bmp.Save("test.png", System.Drawing.Imaging.ImageFormat.Png);
Take a look at Can you make an alpha transparent PNG with C#?