2008-10-09 14 views
10

Я пытаюсь вернуть прозрачный GIF из страницы .aspx для отображения на веб-странице. Я пытаюсь получить изображение с прозрачностью, но я просто продолжаю получать черное, где изображение должно быть прозрачным.Как рисовать прозрачное изображение с помощью System.Drawing?

Кто-нибудь знает, что я делаю неправильно?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ 
    Handles Me.Load 
    '' Change the response headers to output a GIF image. 
    Response.Clear() 
    Response.ContentType = "image/gif" 

    Dim width = 110 
    Dim height = width 

    '' Create a new 32-bit bitmap image 
    Dim b = New Bitmap(width, height) 

    '' Create Grahpics object for drawing 
    Dim g = Graphics.FromImage(b) 

    Dim rect = New Rectangle(0, 0, width - 1, height - 1) 

    '' Fill in with Transparent 
    Dim tbrush = New System.Drawing.SolidBrush(Color.Transparent) 
    g.FillRectangle(tbrush, rect) 

    '' Draw Circle Border 
    Dim bPen = Pens.Red 
    g.DrawPie(bPen, rect, 0, 365) 

    '' Fill in Circle 
    Dim cbrush = New SolidBrush(Color.LightBlue) 
    g.FillPie(cbrush, rect, 0, 365) 


    '' Clean up 
    g.Flush() 
    g.Dispose() 

    '' Make Transparent 
    b.MakeTransparent() 

    b.Save(Response.OutputStream, Imaging.ImageFormat.Gif) 
    Response.Flush() 
    Response.End() 
End Sub 
+0

Я удалил свой пост, чтобы он не загромождал это. – mattlant 2008-10-09 23:34:23

ответ

5

К сожалению, нет простого способа создания прозрачного Gif с использованием объекта Bitmap. (См. this KB article)

В качестве альтернативы вы можете использовать формат PNG, который поддерживает прозрачность с помощью кода, который вы используете.

6

Да, как заявил Джером, в любом случае создать прозрачный GIF с использованием объекта Bitmap не будет. Дерьмо!

Ну, во всяком случае, я изменил свой код, чтобы создать PNG, и все работает так, как ожидалось.

Существует одна небольшая работа вокруг, которую мне нужно было сделать, поскольку вы не можете напрямую писать PNG в OutputStream. Мне нужно было написать PNG в MemoryStream, а затем записать это в OutputStream.

Вот окончательный код для моей реализации:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ 
    Handles Me.Load 
    '' Change the response headers to output a JPEG image. 
    Response.Clear() 
    Response.ContentType = "image/png" 

    Dim width = 11 
    Dim height = width 

    '' Create a new 32-bit bitmap image 
    Dim b = New Bitmap(width, height) 

    '' Create Grahpics object for drawing 
    Dim g = Graphics.FromImage(b) 

    '' Fill the image with a color to be made Transparent after drawing is finished. 
    g.Clear(Color.Gray) 

    '' Get rectangle where the Circle will be drawn 
    Dim rect = New Rectangle(0, 0, width - 1, height - 1) 

    '' Draw Circle Border 
    Dim bPen = Pens.Black 
    g.DrawPie(bPen, rect, 0, 365) 

    '' Fill in Circle 
    Dim cbrush = New SolidBrush(Color.Red) 
    g.FillPie(cbrush, rect, 0, 365) 

    '' Clean up 
    g.Flush() 
    g.Dispose() 

    '' Make Transparent 
    b.MakeTransparent(Color.Gray) 

    '' Write PNG to Memory Stream then write to OutputStream 
    Dim ms = New MemoryStream() 
    b.Save(ms, Imaging.ImageFormat.Png) 
    ms.WriteTo(Response.OutputStream) 

    Response.Flush() 
    Response.End() 
End Sub 
4

Это возможно, но не легко
Если вы в состоянии использовать небезопасный код в проекте, есть несколько методов, в используйте указатели для копирования таблицы цветов и обеспечения прозрачности.

Образец формы приложения Боба Пауэлла можно найти здесь http://www.bobpowell.net/giftransparency.htm. Несколько лет назад я использовал вариацию этого метода в веб-обработчике, который попадал примерно в 10 миллионов раз в месяц, и, похоже, он работал нормально.

Если вы используете только ограниченный цветовой палитры, вы можете уменьшить обработку таблицы цветов только до нужных вам цветов (не помню точно, как я это сделал).

Это, как говорится, png является метрическим crapload легче.

2

вот некоторый код, для которого gif (который уже имеет прозрачность в нем) преобразован (предполагается, что вы хотите изменить его размер) в растровом изображении, а затем может быть правильно отображен с его прозрачностью.

imagePath = System.Web.HttpContext.Current.Request.MapPath(libraryPath + reqImageFile); 
System.Drawing.Image image = null; 
Bitmap resizedImage = null; 

if (reqWidth == 0) { reqWidth = image.Width; } 
if (reqHeight == 0) { reqHeight = image.Height; } 
image = System.Drawing.Image.FromFile(imagePath); 
reqWidth = image.Width; 
reqHeight = image.Height; 

//here is the transparency 'special' treatment 
resizedImage = new Bitmap(reqWidth, reqHeight, PixelFormat.Format8bppIndexed); 
ColorPalette pal = resizedImage.Palette; 
for (int i = 0; i < pal.Entries.Length; i++) 
{ 
     Color col = pal.Entries[i]; 
     pal.Entries[i] = Color.FromArgb(0, col.R, col.G, col.B); 
} 
resizedImage.Palette = pal; 
BitmapData src = ((Bitmap)image).LockBits(new Rectangle(0, 0, reqWidth, reqHeight), ImageLockMode.ReadOnly, image.PixelFormat); 
BitmapData dst = resizedImage.LockBits(new Rectangle(0, 0, resizedImage.Width, resizedImage.Height), 
ImageLockMode.WriteOnly, resizedImage.PixelFormat); 
((Bitmap)image).UnlockBits(src); 
resizedImage.UnlockBits(dst); 

Удачи вам!

Grégoire Lafortune