现在需要在asp.net 中生成图片, 需要用到 GDI 的 ExtFloodFill 方法 来填充区域, 但我找遍 GDI+也没发现有这个函数, 无奈之下只好用 GDI 来完成, 以下为部分代码 Dim image As Image = image.FromFile(Server.MapPath("p.bmp"))
Dim G As Graphics = Graphics.FromImage(image)' 得到 HDC
Dim hdc As IntPtr = G.GetHdc()
Dim oldBrush As IntPtr = SelectObject(hdc, GetStockObject(GRAY_BRUSH))
ExtFloodFill(hdc, 290, 195, GetPixel(hdc, 290, 195), FLOODFILLSURFACE)
G.ReleaseHdc(hdc)
image.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
image.Dispose()
G.Dispose()该图片的 (270, 150) - (300, 220) 是封闭区域, 所以在 (290, 195) 处取点是一定行的奇怪的是 ExtFloodFill 方法却将整幅图片全填充为灰色的了
但如果我写了Rectangle(hdc, 10, 10, 50, 50);
ExtFloodFill(hdc, 20, 20, GetPixel(20, 20), FLOODFILLSURFACE);
却能正常填充换句话说: 对于我用 GDI 在里面绘制的封闭区域, ExtFloodFill 能正常操作
但对于原图中已有的封闭区域, ExtFloodFill 却得到错误的执行结果注: 同样的图片, 同样功能的代码在 VC 中却能正常执行, 所以图片是一定没问题的请求解答
Dim G As Graphics = Graphics.FromImage(image)' 得到 HDC
Dim hdc As IntPtr = G.GetHdc()
Dim oldBrush As IntPtr = SelectObject(hdc, GetStockObject(GRAY_BRUSH))
ExtFloodFill(hdc, 290, 195, GetPixel(hdc, 290, 195), FLOODFILLSURFACE)
G.ReleaseHdc(hdc)
image.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
image.Dispose()
G.Dispose()该图片的 (270, 150) - (300, 220) 是封闭区域, 所以在 (290, 195) 处取点是一定行的奇怪的是 ExtFloodFill 方法却将整幅图片全填充为灰色的了
但如果我写了Rectangle(hdc, 10, 10, 50, 50);
ExtFloodFill(hdc, 20, 20, GetPixel(20, 20), FLOODFILLSURFACE);
却能正常填充换句话说: 对于我用 GDI 在里面绘制的封闭区域, ExtFloodFill 能正常操作
但对于原图中已有的封闭区域, ExtFloodFill 却得到错误的执行结果注: 同样的图片, 同样功能的代码在 VC 中却能正常执行, 所以图片是一定没问题的请求解答
解决方案 »
- 查询xml数据结果显示到datalist中
- 如何保存一个有vba脚本的.xls表格?
- 请教:在<%#DataBinder.Eval(Container.DataItem,("news")%>,只想显示,("news") 中 前两个字符 应该怎么显示呢,在急等!!急!
- 如何给服务器控件套用 群CSS?
- javascript 的confirm问题
- 省市对应ip数据库用什么样的好啊,随便下载的可以吗?
- WEB APP制作安装程序的问题
- 以前正常,今天突然提示“SQL Server 不存在或访问被拒绝”?!急!
- 无法执行web form,请问怎莫办?
- 紧急求救!datagrid的删除问题!!
- 水晶报表中的切换字段视图按钮~~~
- b/s系统解决方案
它会在 DC 中填充图片, 方法是: 从指定的点开始, 一直向四周填充, 直到碰到颜色值不是 第四个参数值给定的颜色为止(也就是遇到边界)它比 FloodFill 高级 的地方就是它可用于多种颜色边界的填充, 但 FloodFill 只能填充边界值为一种颜色的区域如果各位看懂了这个函数的用法, 就会明白,用路径\区域什么的来填充都是达不到要求的, 因为路径是不确定的, 它只是碰到边界才会停止
原文如下:
Searching the web I found out there may be a mismatch with the GDI+ color and GDI color (GDI interprets the color in another way, so it cannot flood fill any area because the pixels never match); it says:
Use the ColorTranslator to create a GDI compatible COLORREF from the GDI+ Color structure.
Dim image As New Bitmap(Server.MapPath("p.png"))
Dim G As Graphics = Graphics.FromImage(image)
G.SmoothingMode = Drawing2D.SmoothingMode.None
Dim clr As Color = image.GetPixel(290, 195)
Dim bmp As Imaging.BitmapData = image.LockBits(New Rectangle(0, 0, image.Width, image.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
FillBmp(New Point(290, 195), bmp, Color.Red, clr)
image.UnlockBits(bmp)
image.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
image.Dispose()
G.Dispose()
End Sub
Private Function CheckPixel(ByVal pos As Point, ByRef bmp As Imaging.BitmapData) As Boolean
Return (pos.X > -1) And (pos.Y > -1) And (pos.X < bmp.Width) And (pos.Y < bmp.Height)
End Function Private Function GetPixel(ByVal pos As Point, ByRef bmp As Imaging.BitmapData) As Color
If (CheckPixel(pos, bmp)) Then
Dim offset As Int32 = pos.Y * bmp.Stride + (3 * pos.X)
Return Color.FromArgb(Marshal.ReadByte(bmp.Scan0, offset + 2), _
Marshal.ReadByte(bmp.Scan0, offset + 1), _
Marshal.ReadByte(bmp.Scan0, offset))
Else
Return Color.FromArgb(0, 0, 0)
End If
End Function Private Sub SetPixel(ByVal pos As Point, ByRef bmp As Imaging.BitmapData, ByVal c As Color)
If (CheckPixel(pos, bmp)) Then
Dim offset As Int32 = pos.Y * bmp.Stride + (3 * pos.X)
Marshal.WriteByte(bmp.Scan0, offset + 2, c.R)
Marshal.WriteByte(bmp.Scan0, offset + 1, c.G)
Marshal.WriteByte(bmp.Scan0, offset, c.B)
'Marshal.WriteByte(bmp.Scan0, offset + 3, CByte(255))
End If
End Sub Private Sub FillBmp(ByVal pt As Point, ByRef bmp As Imaging.BitmapData, ByVal c As Color, ByVal orgc As Color)
Dim curPos As New Point(0, 0)
Dim stk As New Stack
stk.Push(pt)
Do
curPos = DirectCast(stk.Pop(), Point)
SetPixel(curPos, bmp, c)
If (GetPixel(New Point(curPos.X + 1, curPos.Y), bmp).ToArgb() = orgc.ToArgb()) Then
stk.Push(New Point(curPos.X + 1, curPos.Y))
End If If (GetPixel(New Point(curPos.X, curPos.Y - 1), bmp).ToArgb() = orgc.ToArgb()) Then
stk.Push(New Point(curPos.X, curPos.Y - 1))
End If If (GetPixel(New Point(curPos.X - 1, curPos.Y), bmp).ToArgb() = orgc.ToArgb()) Then
stk.Push(New Point(curPos.X - 1, curPos.Y))
End If
If (GetPixel(New Point(curPos.X, curPos.Y + 1), bmp).ToArgb() = orgc.ToArgb()) Then
stk.Push(New Point(curPos.X, curPos.Y + 1))
End If
Loop While (stk.Count > 0)
stk.Clear()
End Sub