Как рисовать прозрачное изображение с помощью System.Drawing?
Я пытаюсь вернуть прозрачный GIF с страницы .aspx для отображения на веб-странице. Я пытаюсь получить изображение с прозрачностью, но я просто продолжаю получать черное, где изображение должно быть прозрачным.
Кто-нибудь знает, что я делаю неправильно?
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
Ответы
Ответ 1
К сожалению, нет простого способа создания прозрачного Gif с использованием объекта Bitmap. (См. эту статью в KB)
В качестве альтернативы вы можете использовать формат PNG, который поддерживает прозрачность с помощью кода, который вы используете.
Ответ 2
Да, как заявил Джером, в любом случае создать прозрачный 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
Ответ 3
Возможно, но нелегко
Если вы можете использовать небезопасный код в своем проекте, есть несколько способов использовать указатели для копирования таблицы цветов и обеспечения прозрачности.
Приложение форм форм от Bob Powell доступно здесь http://www.bobpowell.net/giftransparency.htm. Несколько лет назад я использовал вариацию этого метода в веб-обработчике, который попадал примерно в 10 миллионов раз в месяц, и, похоже, он работал нормально.
Если вы используете только ограниченную цветовую палитру, вы можете уменьшить обработку таблицы цветов только до нужных вам цветов (не помню точно, как я это сделал...).
Как сказано, png - это метрическая диаграмма легче.
Ответ 4
вот некоторый код, чтобы иметь 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);
Удачи!
Грегуар Лафортун