我需要创建一个小而简单的TIFF图像,它只是白色背景上的黑色文本,作为我们在多个产品中使用的支持库的一部分。 (想想简单的收据或存款票,那种事)。我不想使用任何第三方库,以避免要求我们为使用该库的所有现有产品添加其他依赖项。
基于this question的代码,我几乎只使用WPF解决了问题。 TIFF是正确创建和渲染的,但文本质量很糟糕。据我所知,问题是RenderTargetBitmap
,至少我使用它的方式,没有做任何类型的抗锯齿,不使用ClearType,或者在渲染纯文本时非常糟糕,例如:
我已经阅读了类似的问题,例如this one或this one,但他们似乎都在讨论如何从视觉控件或窗口句柄捕获文本而不降低质量。我完全不在屏幕上这样做,所以我不清楚是否/如何将这些解决方案应用于我的问题。
我目前正在做的是:
var visual = new DrawingVisual();
using (var draw = visual.RenderOpen())
{
// 'background' is a pre-loaded blank white bitmap
draw.DrawImage(background, new Rect(0, 0, IMG_WIDTH, IMG_HEIGHT));
var font = new Typeface("Segoe UI");
Func<string, FormattedText> format = s => new FormattedText(
s,
CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
font,
16,
Brushes.Black);
draw.DrawText(format("Some text"), new Point(HEADER_LEFT, HEADER_TOP);
// Call draw.DrawText a whole bunch more times.
.
.
.
}
var render = new RenderTargetBitmap(IMG_WIDTH, IMG_HEIGHT, IMG_DPI, IMG_DPI, PixelFormats.Default);
render.Render(visual);
var encoder = new TiffBitmapEncoder()
{
Compression = TiffCompressOption.Ccitt4
};
encoder.Frames.Add(BitmapFrame.Create(render));
var stream = new MemoryStream();
encoder.Save(stream);
还有什么东西我可以放在那里以使文本质量比它更好吗?
答案 0 :(得分:1)
请勿使用Ccitt4
,仅适用于黑白图像。请改为Default
。
更新:
这是一个TT字体,你试图以小尺寸渲染它,无论你做什么它都会看起来很糟糕。不过,如果你坚持,那么不要使用视觉。屏幕元素使用硬件加速,当您将它们与渲染目标一起使用时,它必须回归到软件方法,这种方法并不总是像素对像素一样。无论哪种方式,你总是得到至少一些别名。如果你确实想要正确的双色调,那么你将不得不使用一个将使用GDI的Graphics对象:
var bitmap = new Bitmap(512, 256);
var graphics = Graphics.FromImage(bitmap);
graphics.Clear(System.Drawing.Color.White);
var font = new Font("Segoe UI", 16);
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
graphics.DrawString("Hello World", font, System.Drawing.Brushes.Black, 0, 0);
ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/tiff");
var myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
bitmap.Save(@"myimage.tif", myImageCodecInfo, myEncoderParameters);
graphics.Dispose();
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
结果(SO本身有点模糊):