2013-10-04 49 views
0

我在這裏找到了一些很棒的代碼,並在我的應用程序中實現了它,雖然它是「工作」的,但模糊效果還不夠強,無法真正實現它),它實際上已經模糊了任何東西。如何在Windows窗體中增加高斯模糊強度

的代碼是(很長,不好意思):

Bitmap screenshot = null; 
    void BlurForm() 
    { 
     /* 
     The best time (I assume) is to change the blur when the user as left the window, 
     as opposed to doing it when they want to open the window, since this may be a 
     little intensive. 
     */ 
     screenshot = null; 
     blurred.Image = null; // This variable is the PictureBox that's on the Form 

     screenshot = Screenshot.TakeSnapshot(this); 
     BitmapFilter.GaussianBlur(screenshot, 4); 

     blurred.Image = screenshot; 
     blurred.SendToBack(); 
    } 

    public class ConvMatrix 
    { 
     public int TopLeft = 0, TopMid = 0, TopRight = 0; 
     public int MidLeft = 0, Pixel = 1, MidRight = 0; 
     public int BottomLeft = 0, BottomMid = 0, BottomRight = 0; 
     public int Factor = 1; 
     public int Offset = 0; 
     public void SetAll(int nVal) 
     { 
      TopLeft = TopMid = TopRight = MidLeft = Pixel = MidRight = BottomLeft = BottomMid = BottomRight = nVal; 
     } 
    } 

    public class BitmapFilter 
    { 
     private static bool Conv3x3(Bitmap b, ConvMatrix m) 
     { 
      // Avoid divide by zero errors 
      if (0 == m.Factor) return false; 

      Bitmap bSrc = (Bitmap)b.Clone(); 

      // GDI+ still lies to us - the return format is BGR, NOT RGB. 
      BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
      BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 

      int stride = bmData.Stride; 
      int stride2 = stride * 2; 
      System.IntPtr Scan0 = bmData.Scan0; 
      System.IntPtr SrcScan0 = bmSrc.Scan0; 

      unsafe 
      { 
       byte* p = (byte*)(void*)Scan0; 
       byte* pSrc = (byte*)(void*)SrcScan0; 

       int nOffset = stride + 6 - b.Width * 3; 
       int nWidth = b.Width - 2; 
       int nHeight = b.Height - 2; 

       int nPixel; 

       for (int y = 0; y < nHeight; ++y) 
       { 
        for (int x = 0; x < nWidth; ++x) 
        { 
         nPixel = ((((pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) + 
          (pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) + 
          (pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight))/m.Factor) + m.Offset); 

         if (nPixel < 0) nPixel = 0; 
         if (nPixel > 255) nPixel = 255; 

         p[5 + stride] = (byte)nPixel; 

         nPixel = ((((pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) + 
          (pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) + 
          (pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight))/m.Factor) + m.Offset); 

         if (nPixel < 0) nPixel = 0; 
         if (nPixel > 255) nPixel = 255; 

         p[4 + stride] = (byte)nPixel; 

         nPixel = ((((pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) + 
          (pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) + 
          (pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight))/m.Factor) + m.Offset); 

         if (nPixel < 0) nPixel = 0; 
         if (nPixel > 255) nPixel = 255; 

         p[3 + stride] = (byte)nPixel; 

         p += 3; 
         pSrc += 3; 
        } 

        p += nOffset; 
        pSrc += nOffset; 
       } 
      } 

      b.UnlockBits(bmData); 
      bSrc.UnlockBits(bmSrc); 

      return true; 
     } 

     public static bool GaussianBlur(Bitmap b, int nWeight /* default to 4*/) 
     { 
      ConvMatrix m = new ConvMatrix(); 
      m.SetAll(1); 
      m.Pixel = nWeight; 
      m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 2; 
      m.Factor = nWeight + 12; 

      return BitmapFilter.Conv3x3(b, m); 
     } 
    } 

    class Screenshot 
    { 
     public static Bitmap TakeSnapshot(Control ctl) 
     { 
      Bitmap bmp = new Bitmap(ctl.Size.Width, ctl.Size.Height); 
      using (Graphics g = System.Drawing.Graphics.FromImage(bmp)) 
      { 
       g.CopyFromScreen(
        ctl.PointToScreen(ctl.ClientRectangle.Location), 
        new Point(0, 0), ctl.ClientRectangle.Size 
       ); 
      } 
      return bmp; 
     } 
    } 

我試圖改變在那裏每一個價值,它並不重要的值(S)我改變,我做不到讓它具有更強的模糊效果。我如何增加高斯模糊的強度?

窗體是80%不透明的,所以你會看到的模糊效果是窗戶壁紙或窗體背後的任何東西 - 但模糊。唯一的問題(正如我所說的)是模糊不強。

+2

代碼太原始了,請使用[更好的庫](http://www.aforgenet.com/framework/docs/html/f074e0dd-865c-fd5f-ba0a-80e336a0eaea.htm)。 –

+0

@HansPassant可以將AForge用於商業應用程序嗎? – uSeRnAmEhAhAhAhAhA

+1

只要遠離視頻,它就是LGPL。 –

回答

1

在對代碼進行掃描之後,它看起來像模糊濾鏡一樣只能在3x3的區域進行硬編碼,嚴重限制了它可以製作圖像的模糊程度。

除非我弄錯了,否則顯着增加模糊量的唯一方法是找到更復雜的實現。

+0

謝謝@Smallhacker,我會繼續探索,看看我能想出什麼。我在這裏的某處讀到了一條評論,他們說要讓它更加模糊,你只需要繼續添加另一個位圖,但所有這些都會讓它變得更加不透明。 – uSeRnAmEhAhAhAhAhA