现在需要在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 中却能正常执行, 所以图片是一定没问题的请求解答

解决方案 »

  1.   

    各位兄弟姐妹, 难道没人知道么路过的请帮忙顶一下, TKS
      

  2.   

    GDI 的 ExtFloodFill 函数的具体意义不知道是什么,GDI+中应该使用GraphicsPath确定填充路径,然后使用new Region(m_GraphicsPath);绑定到Region上。
      

  3.   

    ExtFloodFill 的作用是 (当最后一个参数为 FLOODFILLSURFACE)时
    它会在 DC 中填充图片, 方法是: 从指定的点开始, 一直向四周填充, 直到碰到颜色值不是 第四个参数值给定的颜色为止(也就是遇到边界)它比 FloodFill 高级 的地方就是它可用于多种颜色边界的填充, 但 FloodFill 只能填充边界值为一种颜色的区域如果各位看懂了这个函数的用法, 就会明白,用路径\区域什么的来填充都是达不到要求的, 因为路径是不确定的, 它只是碰到边界才会停止
      

  4.   

    在 CodeGuru 上搜一下, 大概意思是说 GDI+ 对颜色的处理和 GDI 不一样, 需要转换一下
    原文如下: 
    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.
      

  5.   

    http://dotnet.aspx.cc/ShowDetail.aspx?id=45E7E33C-F149-450E-B5D5-832958C20538
      

  6.   

    http://blog.csdn.net/codeangel/archive/2005/06/20/398860.aspx
      

  7.   

    自已找资料解决了, 如果后来人有遇到同样的问题, 可供参考自已写函数实现 ExtFloodFill 的功能        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                    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