I have a multi-browser page that shows vertical text.
As an ugly hack to get text to render vertically in all browsers I've created a custom page handler that returns a PNG with the text drawn vertically.
Here's my basic code (C#3, but small changes to any other version down to 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 ); } }
This creates an image that looks how I want it to, except that the transparency is index based. As I'm returning a PNG it could support a proper alpha transparency.
Is there any way to do this in .net?
Thanks to Vlix (see comments) I've made some changes, though it still isn't right:
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 ); } }
Now the alpha appears to work, but the text appears blocky - as if it still has the jaggie edges but against a black background.
Is this some bug with .Net/GDI+? I've already found that it fails for even index transparencies for gifs, so I don't have much confidence it it.
This image shows the two ways this goes wrong:
The top image shows it with no white background or MakeTransparent
call. The second with the background filled with white and then MakeTransparent
called to add the index transparency.
Neither of these is correct - the second image has white aliasing jaggies that I don't want, the first appears to be solidly aliased against black.
PNG files support transparency, but JPGs do not. If you save a PNG image as a JPG file, the JPG format doesn't know what to do with the alpha channel. That's why all the transparency turns into an opaque white background instead.
To fix the text "blockiness", can't you just do...
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
after this line...
Graphics g = Graphics.FromImage( (Image) image );
IIRC you need to specify the PixelFormat in the bitmap constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With