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

请求检查基于颜色缩减的图像尺寸压缩VB.NET代码

Issues in Your Image Compression VB.NET Code

Let’s walk through your code step by step to spot problems and show you how to fix them:

Common Issues Across Both Buttons

  • Incorrect Variable Declaration: In VB.NET, Dim a,b,c As Integer only sets c as an Integer—a and b default to untyped Object variants. This causes unnecessary performance overhead and potential bugs. Always declare each variable explicitly: Dim a As Integer, b As Integer, c As Integer.
  • Case-Sensitive Color Property Access: .NET’s Color class uses uppercase property names (e.g., Color.A, Color.R, Color.G, Color.B). Your lowercase a, b, c references will throw compile errors since those properties don’t exist.
  • Unmanaged Resource Leaks: You don’t dispose of Bitmap or OpenFileDialog objects, which can lead to memory leaks over time. Wrap these in Using statements to ensure they’re cleaned up automatically.
  • Slow GetPixel/SetPixel: These methods are inefficient for large images because they access pixel data one at a time. For better performance, use Bitmap.LockBits to manipulate pixel data directly in memory (we’ll stick with GetPixel/SetPixel in the fixed code for simplicity, but switch to LockBits for big images).
  • JPEG Transparency Limitation: JPEG doesn’t support alpha channels. If your source image has transparency, saving it as JPEG will lose that data—use PNG instead if you need to preserve transparency.

Button2_Click Specific Issues

  1. Wrong Bitmap Dimensions: You create bmr with New Bitmap(height, height)—this forces both width and height to match the original image’s height, which will stretch or squish the output. It should be New Bitmap(width, height).
  2. Misused Color.FromArgb Overload: Color.FromArgb(a,b,c) creates an RGB color with full alpha (255). If you want to preserve the original alpha channel, use the 4-parameter overload: Color.FromArgb(alpha, red, green, blue). Your code also uses b and c without mapping to actual color channels (you likely meant R, G, and B).
  3. Redundant Variable Reset: Setting a = 0 : b = 0 : c = 0 at the end of the inner loop is unnecessary—variables are reinitialized each iteration anyway.

Button1_Click Specific Issues

  1. Incorrect Dimension Calculation: Using floating-point division (bmp.Width / 2) + 1 can lead to wrong dimensions. Use integer division with (bmp.Width + 1) \ 2 to get the correct rounded-up width for 2x2 pixel averaging.
  2. Truncated Loop Range: For i = 0 To wid - 2 skips the last pixel in the width dimension. Change this to For i = 0 To wid - 1 to process all pixels in the new bitmap.
  3. Unused Variable: imgSource is declared but never used—remove it to clean up your code.
  4. Invalid Color Channel Averaging: Your code averages cc.a, cc.b, and cc.c (invalid properties) instead of the actual cc.R, cc.G, cc.B (and cc.A if you want to preserve alpha).

Fixed Code Example

Here’s the revised code with all issues addressed, plus JPEG quality control and edge-case handling:

Imports System.Drawing.Imaging
Imports System.Math

Public Class Form1
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Using ofd As New OpenFileDialog()
            If ofd.ShowDialog() = DialogResult.OK Then
                Using bmp As New Bitmap(ofd.FileName)
                    PictureBox.Image = bmp.Clone() ' Clone to avoid locking the original file
                    Dim width As Integer = bmp.Width
                    Dim height As Integer = bmp.Height

                    Using bmr As New Bitmap(width, height)
                        For i = 0 To width - 1
                            For j = 0 To height - 1
                                Dim originalColor As Color = bmp.GetPixel(i, j)
                                ' Halve each color channel (integer division for performance)
                                Dim newAlpha As Integer = originalColor.A \ 2
                                Dim newRed As Integer = originalColor.R \ 2
                                Dim newGreen As Integer = originalColor.G \ 2
                                Dim newBlue As Integer = originalColor.B \ 2

                                ' Preserve alpha with 4-parameter overload
                                bmr.SetPixel(i, j, Color.FromArgb(newAlpha, newRed, newGreen, newBlue))
                            Next
                        Next

                        PictureBox2.Image = bmr.Clone()
                        ' Save with custom JPEG quality (adjust 70 to balance size/quality, 0-100)
                        Dim jpegParams As New EncoderParameters(1)
                        jpegParams.Param(0) = New EncoderParameter(Encoder.Quality, 70L)
                        bmr.Save("image2.jpg", GetEncoder(ImageFormat.Jpeg), jpegParams)
                    End Using
                End Using
            End If
        End Using
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Using ofd As New OpenFileDialog()
            If ofd.ShowDialog() = DialogResult.OK Then
                Using bmp As New Bitmap(ofd.FileName)
                    PictureBox.Image = bmp.Clone()
                    ' Correct dimension calculation for 2x2 pixel averaging
                    Dim wid As Integer = (bmp.Width + 1) \ 2
                    Dim hgt As Integer = (bmp.Height + 1) \ 2

                    Using bmr As New Bitmap(wid, hgt)
                        For i = 0 To wid - 1
                            For j = 0 To hgt - 1
                                Dim totalAlpha As Integer = 0
                                Dim totalRed As Integer = 0
                                Dim totalGreen As Integer = 0
                                Dim totalBlue As Integer = 0
                                Dim pixelCount As Integer = 0

                                ' Handle edge cases where original image has odd dimensions
                                For x = 0 To 1
                                    Dim originalX As Integer = i * 2 + x
                                    If originalX >= bmp.Width Then Continue For

                                    For y = 0 To 1
                                        Dim originalY As Integer = j * 2 + y
                                        If originalY >= bmp.Height Then Continue For

                                        Dim pixelColor As Color = bmp.GetPixel(originalX, originalY)
                                        totalAlpha += pixelColor.A
                                        totalRed += pixelColor.R
                                        totalGreen += pixelColor.G
                                        totalBlue += pixelColor.B
                                        pixelCount += 1
                                    Next
                                Next

                                ' Calculate averages (avoid division by zero)
                                Dim avgAlpha As Integer = If(pixelCount > 0, totalAlpha \ pixelCount, 0)
                                Dim avgRed As Integer = If(pixelCount > 0, totalRed \ pixelCount, 0)
                                Dim avgGreen As Integer = If(pixelCount > 0, totalGreen \ pixelCount, 0)
                                Dim avgBlue As Integer = If(pixelCount > 0, totalBlue \ pixelCount, 0)

                                bmr.SetPixel(i, j, Color.FromArgb(avgAlpha, avgRed, avgGreen, avgBlue))
                            Next
                        Next

                        PictureBox1.Image = bmr.Clone()
                        ' Save with custom JPEG quality
                        Dim jpegParams As New EncoderParameters(1)
                        jpegParams.Param(0) = New EncoderParameter(Encoder.Quality, 70L)
                        bmr.Save("test.jpg", GetEncoder(ImageFormat.Jpeg), jpegParams)
                    End Using
                End Using
            End If
        End Using
    End Sub

    ' Helper method to get JPEG encoder for quality settings
    Private Function GetEncoder(format As ImageFormat) As ImageCodecInfo
        Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
        For Each codec As ImageCodecInfo In codecs
            If codec.FormatID = format.Guid Then
                Return codec
            End If
        Next
        Return Nothing
    End Function
End Class

Additional Notes

  • The GetEncoder helper lets you adjust JPEG compression quality to balance file size and image clarity.
  • We use Clone() when assigning to PictureBox.Image to avoid locking the original file (so you can overwrite it later without errors).
  • The 2x2 averaging code now handles odd-sized images correctly, so it never tries to access pixels outside the original bitmap’s bounds.

内容的提问来源于stack exchange,提问作者Ammar Mohammed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:42:50