You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET中Bitmap图像模糊效果实现求助:现有代码效果不佳求资料

Hey there! The approach you're using right now (offsetting and overlaying semi-transparent copies) is a quick-and-dirty pseudo-blur, but it's prone to edge artifacts, uneven blurring, and poor performance as your BlurSize increases. Let's fix that with proper, high-quality blur methods tailored for Bitmap images in VB.NET:

High-Quality Bitmap Blur Solutions

Why Your Current Code Isn't Working

Your current method works by drawing the same image multiple times with slight offsets and reduced opacity. This creates a "smudged" look, but it has major drawbacks:

  • Uneven blur: Pixels near the edge get clipped, leading to distorted edges
  • No natural diffusion: It doesn't mimic the human eye's perception of blur (Gaussian blur is the industry standard)
  • Performance issues: The number of draw calls scales with BlurSize², which gets slow fast for larger values

Option 1: Built-in Blur Effect (.NET 5+ / .NET Core)

If you're working with .NET 5 or later (or using the System.Drawing.Common NuGet package), you can leverage GDI+'s native BlurEffect for clean, fast blurs with minimal code.

Code Example:

Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D

Public Function ApplyHighQualityBlur(ByVal sourceBitmap As Bitmap, ByVal blurRadius As Integer) As Bitmap
    ' Create a new bitmap to hold the blurred result
    Dim blurredBitmap As New Bitmap(sourceBitmap.Width, sourceBitmap.Height)
    
    Using g As Graphics = Graphics.FromImage(blurredBitmap)
        ' Enable high-quality rendering settings
        g.SmoothingMode = SmoothingMode.HighQuality
        g.InterpolationMode = InterpolationMode.HighQualityBicubic
        g.PixelOffsetMode = PixelOffsetMode.HighQuality
        
        ' Configure the blur effect
        Dim blurEffect As New BlurEffect With {
            .Radius = blurRadius, ' Controls blur intensity (1-20 is ideal)
            .Optimization = BlurOptimization.Balanced ' Balances speed and quality
        }
        
        ' Draw the original image and apply the blur effect
        g.DrawImage(sourceBitmap, New Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height))
        g.DrawImage(
            sourceBitmap,
            New Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
            0, 0, sourceBitmap.Width, sourceBitmap.Height,
            GraphicsUnit.Pixel,
            Nothing,
            AddressOf BlurEffectCallback,
            blurEffect
        )
    End Using
    
    Return blurredBitmap
End Function

' Callback to apply the blur effect during rendering
Private Sub BlurEffectCallback(ByVal callbackData As Object, ByVal effect As Effect)
    Dim blurEffect As BlurEffect = DirectCast(callbackData, BlurEffect)
    effect.Apply(blurEffect)
End Sub

Option 2: Manual Gaussian Blur (Compatible with .NET Framework)

For older .NET Framework projects, you'll need to implement Gaussian blur manually. This method uses a convolution kernel weighted by a Gaussian distribution to create natural, smooth blurs.

Code Example:

Imports System.Drawing
Imports System.Runtime.InteropServices

Public Module BitmapBlurExtensions
    ''' <summary>
    ''' Applies Gaussian blur to a Bitmap
    ''' </summary>
    ''' <param name="source">Source Bitmap to blur</param>
    ''' <param name="radius">Blur radius (1-20 recommended)</param>
    ''' <returns>Blurred Bitmap</returns>
    Public Function GaussianBlur(ByVal source As Bitmap, ByVal radius As Integer) As Bitmap
        If radius < 1 Then Return DirectCast(source.Clone(), Bitmap)
        
        Dim width As Integer = source.Width
        Dim height As Integer = source.Height
        Dim blurred As New Bitmap(width, height)
        
        ' Lock bitmap data for fast pixel access
        Dim sourceData As BitmapData = source.LockBits(
            New Rectangle(0, 0, width, height),
            ImageLockMode.ReadOnly,
            PixelFormat.Format32bppArgb
        )
        Dim blurredData As BitmapData = blurred.LockBits(
            New Rectangle(0, 0, width, height),
            ImageLockMode.WriteOnly,
            PixelFormat.Format32bppArgb
        )
        
        Dim stride As Integer = sourceData.Stride
        Dim sourceBuffer As Byte() = New Byte(stride * height - 1) {}
        Dim blurredBuffer As Byte() = New Byte(stride * height - 1) {}
        
        ' Copy pixel data to buffers
        Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, sourceBuffer.Length)
        
        ' Generate Gaussian convolution kernel
        Dim kernel As Double() = CreateGaussianKernel(radius)
        Dim kernelSize As Integer = kernel.Length
        
        ' Apply horizontal then vertical blur (separable convolution)
        HorizontalBlur(sourceBuffer, blurredBuffer, width, height, stride, kernel, kernelSize)
        VerticalBlur(blurredBuffer, sourceBuffer, width, height, stride, kernel, kernelSize)
        
        ' Copy processed data back to the blurred bitmap
        Marshal.Copy(sourceBuffer, 0, blurredData.Scan0, sourceBuffer.Length)
        
        ' Unlock bitmap data
        source.UnlockBits(sourceData)
        blurred.UnlockBits(blurredData)
        
        Return blurred
    End Function
    
    ''' <summary>
    ''' Creates a normalized Gaussian kernel
    ''' </summary>
    Private Function CreateGaussianKernel(ByVal radius As Integer) As Double()
        Dim size As Integer = radius * 2 + 1
        Dim kernel As Double() = New Double(size - 1) {}
        Dim sigma As Double = radius / 3.0 ' Standard deviation for Gaussian curve
        Dim sum As Double = 0.0
        
        ' Calculate Gaussian weights
        For i As Integer = -radius To radius
            kernel(i + radius) = Math.Exp(-(i * i) / (2 * sigma * sigma))
            sum += kernel(i + radius)
        Next
        
        ' Normalize kernel so total weight equals 1
        For i As Integer = 0 To size - 1
            kernel(i) /= sum
        Next
        
        Return kernel
    End Function
    
    ''' <summary>
    ''' Applies horizontal blur using the convolution kernel
    ''' </summary>
    Private Sub HorizontalBlur(ByVal source As Byte(), ByVal dest As Byte(), ByVal width As Integer, ByVal height As Integer, ByVal stride As Integer, ByVal kernel As Double(), ByVal kernelSize As Integer)
        Dim radius As Integer = (kernelSize - 1) \ 2
        
        For y As Integer = 0 To height - 1
            For x As Integer = 0 To width - 1
                Dim r, g, b, a As Double
                Dim offset As Integer = y * stride + x * 4
                
                ' Convolve with kernel
                For k As Integer = -radius To radius
                    Dim nx As Integer = Math.Max(0, Math.Min(width - 1, x + k)) ' Clamp to image bounds
                    Dim kernelOffset As Integer = k + radius
                    Dim pixelOffset As Integer = y * stride + nx * 4
                    
                    r += source(pixelOffset + 2) * kernel(kernelOffset)
                    g += source(pixelOffset + 1) * kernel(kernelOffset)
                    b += source(pixelOffset) * kernel(kernelOffset)
                    a += source(pixelOffset + 3) * kernel(kernelOffset)
                Next
                
                ' Write clamped pixel values to destination
                dest(offset) = CByte(Math.Max(0, Math.Min(255, b)))
                dest(offset + 1) = CByte(Math.Max(0, Math.Min(255, g)))
                dest(offset + 2) = CByte(Math.Max(0, Math.Min(255, r)))
                dest(offset + 3) = CByte(Math.Max(0, Math.Min(255, a)))
            Next
        Next
    End Sub
    
    ''' <summary>
    ''' Applies vertical blur using the convolution kernel
    ''' </summary>
    Private Sub VerticalBlur(ByVal source As Byte(), ByVal dest As Byte(), ByVal width As Integer, ByVal height As Integer, ByVal stride As Integer, ByVal kernel As Double(), ByVal kernelSize As Integer)
        Dim radius As Integer = (kernelSize - 1) \ 2
        
        For x As Integer = 0 To width - 1
            For y As Integer = 0 To height - 1
                Dim r, g, b, a As Double
                Dim offset As Integer = y * stride + x * 4
                
                ' Convolve with kernel
                For k As Integer = -radius To radius
                    Dim ny As Integer = Math.Max(0, Math.Min(height - 1, y + k)) ' Clamp to image bounds
                    Dim kernelOffset As Integer = k + radius
                    Dim pixelOffset As Integer = ny * stride + x * 4
                    
                    r += source(pixelOffset + 2) * kernel(kernelOffset)
                    g += source(pixelOffset + 1) * kernel(kernelOffset)
                    b += source(pixelOffset) * kernel(kernelOffset)
                    a += source(pixelOffset + 3) * kernel(kernelOffset)
                Next
                
                ' Write clamped pixel values to destination
                dest(offset) = CByte(Math.Max(0, Math.Min(255, b)))
                dest(offset + 1) = CByte(Math.Max(0, Math.Min(255, g)))
                dest(offset + 2) = CByte(Math.Max(0, Math.Min(255, r)))
                dest(offset + 3) = CByte(Math.Max(0, Math.Min(255, a)))
            Next
        Next
    End Sub
End Module

Usage Tips

  • Blur radius: Stick to values between 1 and 20. Larger radiuses create more intense blur but will slow down processing.
  • Performance optimization: For large images, resize the image to a smaller resolution before blurring, then scale it back up. This drastically reduces the number of pixels to process.
  • Dispose of objects: Always wrap Bitmap and Graphics objects in Using statements to avoid memory leaks.

内容的提问来源于stack exchange,提问作者Geo Concepts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:41