NovelEssay.com Programming Blog

Exploration of Big Data, Machine Learning, Natural Language Processing, and other fun problems.

Converting a text string to a Brushes Color object in C#

We want to dynamically go from a list of Colors (ie, Red, Yellow, White) to the Brush object types shown in my previous article: Adding Text to Images with C# .Net Bitmap objects - We'll show a few solutions for mapping strings to Brush Color objects.


Try this one first. Simply map your string to a Color using the FromName function like this:

Color yellowColor = Color.FromName("Yellow");

Alternatively, you can use a ColorConverter like this:

TypeConverter typeConverter1 = TypeDescriptor.GetConverter(typeof(Color));
TypeConverter typeConverter2 = new ColorConverter();
Color yellowColor2 = (Color)tc.ConvertFromString("Yellow");

Lastly, you can use Reflection on Color or Brush like this:

Color yellowColor3 = (Color)typeof(Color).GetProperty("Yellow").GetValue(null, null);



Adding Text to Images with C# .Net Bitmap objects

This article will show you some examples of how to add text to images with C# .Net Bitmap objects. This works for jpg, png, bitmap, and other image format types.

Procedure Overview:

  1. Create a Bitmap object with your source image.
  2. Create a RectangleF object around your source image.
  3. Create a Graphics object using your source Bitmap object
  4. Set several configuration values on your Graphics object that make the text look better in most cases.
  5. Draw your text string to the rectangle with all of the specified settings.
  6. Flush the changes and save your final output.

Here's some example code that implements the above procedure:

// Load the original image. Can be jpg, png, bmp, etc...
Bitmap bmp = new Bitmap("myImage.jpg");
// Create a rectangle for the entire bitmap
RectangleF rectf = new RectangleF(0, 0, bmp.Width, bmp.Height);
// Create graphic object that will draw onto the bitmap
Graphics g = Graphics.FromImage(bmp);
// ------------------------------------------
// Ensure the best possible quality rendering
// ------------------------------------------
// The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing). One exception is that path gradient brushes do not obey the smoothing mode. Areas filled using a PathGradientBrush are rendered the same way (aliased) regardless of the SmoothingMode property.
g.SmoothingMode = SmoothingMode.AntiAlias;
// The interpolation mode determines how intermediate values between two endpoints are calculated.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Use this property to specify either higher quality, slower rendering, or lower quality, faster rendering of the contents of this Graphics object.
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// This one is important
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
// Create string formatting options (used for alignment)
StringFormat format = new StringFormat()
{
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Center
};
// Draw the text onto the image
g.DrawString("Visit StyleMyImage.com", new Font("Tahoma",8), Brushes.Black, rectf, format);
// Flush all graphics changes to the bitmap
g.Flush();
// Now save or use the bitmap
image.Image = bmp;

The following are common items you may want to customize: Fonts, Size, Color, Text Position, etc...


If you want to change your font type or font size, edit the values you set in this part of the code:

new Font("Tahoma",14)

If you want the text to be Yellow, change the 

Brushes.Black 

to 

Brushes.Yellow


If you want the text to be in the bottom right corner, change the Alignment values in the StringFormat object.

StringFormat format = new StringFormat()
{
Alignment = StringAlignment.Far,
LineAlignment = StringAlignment.Far
};


Finally, if you want to change the Text drawn on to the image, change the first argument passed to g.DrawString from Visit StyleMyImage.com to whatever you'd like it to say.


C# Bitmap Image Scaling for Bmp, Jpg, and Png

How do you scale your bmp, jpg, or png images in C#? Use System.Drawing.BitMap and follow the instructions in this article.


(Be sure to wrap all of your MemoryStreams and Bitmap objects with Using statements, so they get disposed, otherwise you'll have some memory leaks and locks on files.)


First, add references to System.Drawing in your C# Visual Studio project, and you'll want a using statement near the top of your code too:

using System.Drawing;

Then, we'll load up our image in to a Bitmap object and save it to a memory stream like this:

string sourceFile = "c:\my.png";

using (Bitmap srcBitmap = new Bitmap(sourceFile))
using (MemoryStream streamSrc = new MemoryStream())
{
srcBitmap.Save(streamSrc, System.Drawing.Imaging.ImageFormat.Jpeg);
We will calculate the area of the source image using the height and width attributes:
	int sourceImageArea = srcBitmap.Width * srcBitmap.Height;


If the source image area exceeds a threshold, we'll calculate a scale factor that we need to reduce the height and width by. That new scale factor will be applied to get a new width and height.

		float scaleRatio = maxOutputPixelArea;
scaleRatio /= sourceImageArea; // scaleRatio is less than 1
float newW = srcBitmap.Width;
newW *= scaleRatio;
float newH = srcBitmap.Height;
newH *= scaleRatio;

Lastly, we'll create a new Bitmap to save the converted image to with our new dimensions:

		using (Bitmap resizedImg = ResizeImage(srcBitmap, Convert.ToInt32(newW), Convert.ToInt32(newH)))
using (MemoryStream resizedImgStrm = new MemoryStream())
{
resizedImg.Save(resizedImgStrm, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = resizedImgStrm.ToArray();
// Save imageBytes to file, store to Database, or whatever
}


The full code looks like this:

string sourceFile = "c:\my.png";
int maxOutputPixelArea = 3000000;
using (Bitmap srcBitmap = new Bitmap(sourceFile))
using (MemoryStream streamSrc = new MemoryStream())
{
// Convert the image to byte[]
srcBitmap.Save(streamSrc, System.Drawing.Imaging.ImageFormat.Jpeg);
int sourceImageArea = srcBitmap.Width * srcBitmap.Height;
if (sourceImageArea > maxOutputPixelArea)
{
float scaleRatio = maxOutputPixelArea;
scaleRatio /= sourceImageArea; // scaleRatio is less than 1
float newW = srcBitmap.Width;
newW *= scaleRatio;
float newH = srcBitmap.Height;
newH *= scaleRatio;
using (Bitmap resizedImg = ResizeImage(srcBitmap, Convert.ToInt32(newW), Convert.ToInt32(newH)))
using (MemoryStream resizedImgStrm = new MemoryStream())
{
resizedImg.Save(resizedImgStrm, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = resizedImgStrm.ToArray();
// Save imageBytes to file, store to Database, or whatever
}
}


Finally, the ResizeImage code is this:

private static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}