当前位置:  开发笔记 > 编程语言 > 正文

你能用C#做一个alpha透明的PNG吗?

如何解决《你能用C#做一个alpha透明的PNG吗?》经验,为你挑选了4个好方法。

我有一个显示垂直文本的多浏览器页面.

作为一个丑陋的黑客,让文本在所有浏览器中垂直渲染我创建了一个自定义页面处理程序,它返回一个垂直绘制文本的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调用添加索引透明度.

这些都不是正确的 - 第二张图片有我不想要的白色锯齿锯齿,第一张图像看起来是黑色的混合锯齿.



1> pmcilreavy..:

要修复文本"块状",你不能只做...

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

在此之后......

Graphics g = Graphics.FromImage( (Image) image );


实际上这导致了答案 - 默认情况下,这个TextRenderingHint是从系统中读取的,所以当它在服务器上执行此操作(默认情况下使用抗锯齿)时,它会应用clear-type.将此设置为TextRenderingHint.SingleBitPerPixelGridFit修复了我的问题.

2> leppie..:

IIRC你需要在位图构造函数中指定PixelFormat.


事实上,你自己用"g.FillRectangle(Brushes.White,0f,0f,image.Width,image.Height)填充它;" 这是一种不透明的白色.将其更改为透明的,您将拥有它.
如果你试图绘制透明像素,它会.图片在开头填充了非透明像素.

3> MusiGenesis..:

您可以使用Bitmap上的LockBits方法返回BitmapData对象,并自己设置每个像素的Alpha(您也可以使用GetPixel和SetPixel,但这些方法非常慢).看到这个答案.

我知道这肯定有用,因为当我第一次开始使用这种技术时,我将alpha值设置为0,所以我设置的颜色都不可见.

编辑:这是一个鱼眼镜头效果的样本,完全在.NET中完成(使用LockBits):

alt text http://www.freeimagehosting.net/uploads/21ca8300cc.jpg



4> Vilx-..:

对于文本抗锯齿,使用Graphics.TextRenderingHint中的值.我建议不要使用ClearType,因为这只会在LCD显示器(而非CRT)上显示不错,并且可能由于旋转而无效.

PS它是Vilx-,而不是Vlix.:d

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有