You could use the System.Drawing library to create a TIFF image; the library includes text options so you'd just need to work out the right font sizes and positioning.
Once you have a TIFF file created in a stream, you can write that to the document.
I don't have a process that does exactly what you're doing, but I do have bits from other processes that could give you a general idea of the different steps.
I usually target an image size of 2550x3000, which is 8.5″x11″ at 300DPI
Here's an example of code we use to generate stamp images dynamically (you'd want to save it to ImageFormat.Tiff instead of ImageFormat.Bmp so there's some encoder stuff you may want too).
//Create test image at runtime
Bitmap bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp))
{
// Set string format
StringFormat stringFormat = new StringFormat();
// Set horizontal and vertical alignment
// Note this is the alignment within the drawing rectangle, not overall page alignment
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
// Set font rendering and formatting
g.TextRenderingHint = TextRenderingHint.AntiAlias;
System.Drawing.Font line1 = new System.Drawing.Font("Arial", 60, FontStyle.Bold, GraphicsUnit.Point);
System.Drawing.Font line2 = new System.Drawing.Font("Arial", 30, FontStyle.Bold, GraphicsUnit.Point);
System.Drawing.Font line3 = new System.Drawing.Font("Arial", 25, FontStyle.Bold, GraphicsUnit.Point);
// clear background
g.Clear(Color.White);
// draw image content
g.DrawString(type.ToUpper(), line1, Brushes.Black, new Rectangle(0, 0, width, 150), stringFormat);
g.DrawString(vtoken, line2, Brushes.Black, new Rectangle(0, 165, width, 150), stringFormat);
g.DrawString(subtext, line3, Brushes.Black, new Rectangle(0, 245, width, 150), stringFormat);
}
//Convert bitmap to monochrome
BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
bmp = new Bitmap(width, height, bmpData.Stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, bmpData.Scan0);
// copy image to memory stream
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Tiff);
bmp.Dispose();
Here's some code I use to draw a TIFF back to PagePart.Image (we use this in a process that auto-resizes documents that have unnecessarily high dimensions or DPI).
// Move to beginning of memory stream
ms.Seek(0, SeekOrigin.Begin);
// Create write stream
using (Stream writer = page.WritePagePart(PagePart.Image, (int)ms.Length)){
byte[] buffer = new byte[0x8000];
int count;
while((count = ms.Read(buffer, 0, buffer.Length)) > 0){
writer.Write(buffer, 0, count);
}
}
I think ImageFormat.Tiff defaults to LZW or uncompressed, but if you want to force it to use something different, like monochrome for smaller file sizes, then you want something like this:
EncoderParameters encoderParameters = new EncoderParameters(2);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Compression,compressionType[compressionIndex]);
encoderParameters.Param[1] = new EncoderParameter(Encoder.Quality,100L);
// Retrieve encoder
ImageCodecInfo tiffEncoder = GetEncoderInfo("image/tiff");
// Save with existing encoders
newImg.Save(ms,tiffEncoder,encoderParameters);
The compression type arrays it references are defined like so
string[] compressionTypeName = new string[5] {
"no compression",
"CCITT Group 3",
"Facsimile - compatible CCITT Group 3",
"CCITT Group 4(T.6)",
"LZW"
};
long[] compressionType = new long[5] {
(long)EncoderValue.CompressionNone,
(long)EncoderValue.CompressionCCITT3,
(long)EncoderValue.CompressionCCITT3,
(long)EncoderValue.CompressionCCITT4,
(long)EncoderValue.CompressionLZW
};
And the GetEncoderInfo method is as follows
private static ImageCodecInfo GetEncoderInfo(string mimeType){
// Identify and set tiff encoder
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < encoders.Length; i++)
{
if (encoders[i].MimeType == mimeType)
{
return encoders[i];
}
}
return null;
}
However, in your case, you could probably set that with static values and would probably want Group 4 rather than LZW unless you want/need color.
I only needed dynamic since I'm resizing existing images and the source image codecs can vary.