裁剪图像如何适合图像内容?

时间:2019-04-24 02:59:44

标签: vb.net

我的图片如下:

enter image description here

我希望裁切图像适合内容,删除白色区域。

结果:

enter image description here

这是我的代码,可以裁剪图像

Dim fileName = "D:\2018\ori_image.jpg"
        Dim fileNameres = "D:\2018\res_image.jpg"
        Dim CropRect As New System.Drawing.Rectangle(0, 0, 200, 320)
        Dim OriginalImage = System.Drawing.Image.FromFile(fileName)
        Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
        Using grp = Graphics.FromImage(CropImage)
            grp.DrawImage(OriginalImage, New System.Drawing.Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
            OriginalImage.Dispose()
            CropImage.Save(fileNameres)
        End Using

现在,如何获取图像的“位置开始”和“尺寸”内容? 谢谢。

1 个答案:

答案 0 :(得分:2)

您可以使用以下代码删除不需要的区域:

Public Function CropUnwantedBackground(ByVal bmp As Bitmap) As Bitmap
    Dim backColor = GetMatchedBackColor(bmp)

    If backColor.HasValue Then
        Dim bounds = GetImageBounds(bmp, backColor)
        Dim diffX = bounds(1).X - bounds(0).X + 1
        Dim diffY = bounds(1).Y - bounds(0).Y + 1
        Dim croppedBmp = New Bitmap(diffX, diffY)
        Dim g = Graphics.FromImage(croppedBmp)
        Dim destRect = New Rectangle(0, 0, croppedBmp.Width, croppedBmp.Height)
        Dim srcRect = New Rectangle(bounds(0).X, bounds(0).Y, diffX, diffY)
        g.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel)
        Return croppedBmp
    Else
        Return bmp
    End If
End Function

Private Function GetImageBounds(ByVal bmp As Bitmap, ByVal backColor As Color?) As Point()
    Dim c As Color
    Dim width As Integer = bmp.Width, height As Integer = bmp.Height
    Dim upperLeftPointFounded As Boolean = False
    Dim bounds = New Point(1) {}

    For y As Integer = 0 To height - 1

        For x As Integer = 0 To width - 1
            c = bmp.GetPixel(x, y)
            Dim sameAsBackColor As Boolean = ((c.R <= backColor.Value.R * 1.1 AndAlso c.R >= backColor.Value.R * 0.9) AndAlso (c.G <= backColor.Value.G * 1.1 AndAlso c.G >= backColor.Value.G * 0.9) AndAlso (c.B <= backColor.Value.B * 1.1 AndAlso c.B >= backColor.Value.B * 0.9))

            If Not sameAsBackColor Then

                If Not upperLeftPointFounded Then
                    bounds(0) = New Point(x, y)
                    bounds(1) = New Point(x, y)
                    upperLeftPointFounded = True
                Else

                    If x > bounds(1).X Then
                        bounds(1).X = x
                    ElseIf x < bounds(0).X Then
                        bounds(0).X = x
                    End If

                    If y >= bounds(1).Y Then bounds(1).Y = y
                End If
            End If
        Next
    Next

    Return bounds
End Function

Private Function GetMatchedBackColor(ByVal bmp As Bitmap) As Color?
    Dim corners = New Point() {New Point(0, 0), New Point(0, bmp.Height - 1), New Point(bmp.Width - 1, 0), New Point(bmp.Width - 1, bmp.Height - 1)}

    For i As Integer = 0 To 4 - 1
        Dim cornerMatched = 0
        Dim backColor = bmp.GetPixel(corners(i).X, corners(i).Y)

        For j As Integer = 0 To 4 - 1
            Dim cornerColor = bmp.GetPixel(corners(j).X, corners(j).Y)

            If (cornerColor.R <= backColor.R * 1.1 AndAlso cornerColor.R >= backColor.R * 0.9) AndAlso (cornerColor.G <= backColor.G * 1.1 AndAlso cornerColor.G >= backColor.G * 0.9) AndAlso (cornerColor.B <= backColor.B * 1.1 AndAlso cornerColor.B >= backColor.B * 0.9) Then
                cornerMatched += 1
            End If
        Next

        If cornerMatched > 2 Then
            Return backColor
        End If
    Next

    Return Nothing
End Function

类似的事情应该起作用。只需致电CropUnwantedBackground

Dim fileName = "D:\2018\ori_image.jpg"
Dim fileNameres = "D:\2018\res_image.jpg"
Dim CropRect As New System.Drawing.Rectangle(0, 0, 200, 320)
Dim OriginalImage = System.Drawing.Image.FromFile(fileName)
Dim ImageWithoutWhiteArea = CropUnwantedBackground(OriginalImage)
ImageWithoutWhiteArea.Save(fileNameres)