我有一个显示垂直文本的多浏览器页面.
作为一个丑陋的黑客,让文本在所有浏览器中垂直渲染我创建了一个自定义页面处理程序,它返回一个垂直绘制文本的PNG.
这是我的基本代码(C#3,但对其他任何版本的细微更改为1):
Font f = GetSystemConfiguredFont(); //this sets the text to be rotated 90deg clockwise (i.e. down) StringFormat stringFormat = new StringFormat { FormatFlags = StringFormatFlags.DirectionVertical }; SizeF size; // creates 1Kx1K image buffer and uses it to find out how bit the image needs to be to fit the text using ( Image imageg = (Image) new Bitmap( 1000, 1000 ) ) size = Graphics.FromImage( imageg ). MeasureString( text, f, 25, stringFormat ); using ( Bitmap image = new Bitmap( (int) size.Width, (int) size.Height ) ) { Graphics g = Graphics.FromImage( (Image) image ); g.FillRectangle( Brushes.White, 0f, 0f, image.Width, image.Height ); g.TranslateTransform( image.Width, image.Height ); g.RotateTransform( 180.0F ); //note that we need the rotation as the default is down // draw text g.DrawString( text, f, Brushes.Black, 0f, 0f, stringFormat ); //make be background transparent - this will be an index (rather than an alpha) transparency image.MakeTransparent( Color.White ); //note that this image has to be a PNG, as GDI+'s gif handling renders any transparency as black. context.Response.AddHeader( "ContentType", "image/png" ); using ( MemoryStream memStream = new MemoryStream() ) { image.Save( memStream, ImageFormat.Png ); memStream.WriteTo( context.Response.OutputStream ); } }
这会创建一个看起来我想要的图像,除了透明度是基于索引的.当我返回一个PNG时,它可以支持正确的alpha透明度.
在.net中有什么办法吗?
感谢Vlix(见评论)我做了一些改变,虽然它仍然不对:
using ( Bitmap image = new Bitmap( (int) size.Width, (int) size.Height, PixelFormat.Format32bppArgb ) ) { Graphics g = Graphics.FromImage( (Image) image ); g.TranslateTransform( image.Width, image.Height ); g.RotateTransform( 180.0F ); //note that we need the rotation as the default is down // draw text g.DrawString( text, f, Brushes.Black, 0f, 0f, stringFormat ); //note that this image has to be a PNG, as GDI+'s gif handling renders any transparency as black. context.Response.AddHeader( "ContentType", "image/png" ); using ( MemoryStream memStream = new MemoryStream() ) { //note that context.Response.OutputStream doesn't support the Save, but does support WriteTo image.Save( memStream, ImageFormat.Png ); memStream.WriteTo( context.Response.OutputStream ); } }
现在阿尔法似乎工作,但文本看似块状 - 好像它仍然有jaggie边缘,但在黑色背景.
这是.Net/GDI +的一些错误吗?我已经发现它甚至没有GIF的索引透明度,所以我对它没有多少信心.
此图显示了出错的两种方式:
顶部图像显示没有白色背景或MakeTransparent
呼叫.第二个用背景填充白色然后MakeTransparent
调用添加索引透明度.
这些都不是正确的 - 第二张图片有我不想要的白色锯齿锯齿,第一张图像看起来是黑色的混合锯齿.
要修复文本"块状",你不能只做...
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
在此之后......
Graphics g = Graphics.FromImage( (Image) image );
IIRC你需要在位图构造函数中指定PixelFormat.
您可以使用Bitmap上的LockBits方法返回BitmapData对象,并自己设置每个像素的Alpha(您也可以使用GetPixel和SetPixel,但这些方法非常慢).看到这个答案.
我知道这肯定有用,因为当我第一次开始使用这种技术时,我将alpha值设置为0,所以我设置的颜色都不可见.
编辑:这是一个鱼眼镜头效果的样本,完全在.NET中完成(使用LockBits):
alt text http://www.freeimagehosting.net/uploads/21ca8300cc.jpg
对于文本抗锯齿,使用Graphics.TextRenderingHint中的值.我建议不要使用ClearType,因为这只会在LCD显示器(而非CRT)上显示不错,并且可能由于旋转而无效.
PS它是Vilx-,而不是Vlix.:d