Remove Surrounding White Space From An Image

by Kyle Ballard 11/22/2008 5:15:02 PM

The following is from my post on StackOverflow.com

I have a block of product images we received from a customer. Each product image is a picture of something and it was taken with a white background. I would like to crop all the surrounding parts of the image but leave only the product in the middle. Is this possible?

As an example: http://www.5dnet.de/media/catalog/product/d/r/dress_shoes_5.jpg

I don't want all white pixels removed, however I do want the image cropped so that the top-most row of pixels contains one non-white pixel, the left-most vertical row of pixels contains one non-white pixel, bottom-most horizontal row of pixels contains one non-white pixel, etc.

Below is the solution to my problem.  It is not the most glamorous approach, but it works.  I could have use Bitmap.Lockbits() to lock the bitmap in memory and do my processing there, but this approach below sufficed my needs.  It is a pixel by pixel scan of the image. 

Some recommended additions/changes if you are feeling inclined:

- Use Bitmap.Lockbits() to improve performance
- Perform image resizing after the trimming is completed.
- Instead of looking for straight white pixels, you could also exclude near-white pixels (for any shadows).

Start.vb

Imports System.Drawing 
Imports System.IO 
Imports System.Configuration.ConfigurationManager 

Module Start 

    Sub Main() 
        Try 
            Console.WriteLine("") 
            Console.WriteLine("Begin:  Crop Images") 
            CropAllImages() 
        Catch e As Exception 
            Console.WriteLine("Error Message: " & e.Message) 
            Console.WriteLine("----------") 
            Console.WriteLine("Error Stack: " & e.StackTrace) 
        End Try 
    End Sub 

    Sub CropAllImages() 
        Dim iTopMostPixel As Integer, iLeftMostPixel As Integer, iRightMostPixel As Integer, iBottomMostPixel As Integer 
        Dim objBmp As Bitmap, objNewBmp As Bitmap 
        Dim rect As Rectangle 
        For Each oFile As FileInfo In New DirectoryInfo(AppSettings("ImagePath")).GetFiles("*.jpg") 
            objBmp = CType(Bitmap.FromFile(AppSettings("ImagePath") & oFile.Name), Image) 

            iTopMostPixel = GetNonWhitePixel(objBmp, 1) + AppSettings("PaddingTop") ' Get the top most pixel and add any optional padding 
            iLeftMostPixel = GetNonWhitePixel(objBmp, 2) + AppSettings("PaddingLeft") ' Get the left most pixel and add any optional padding 
            iBottomMostPixel = GetNonWhitePixel(objBmp, 3) + AppSettings("PaddingBottom") 
            iRightMostPixel = GetNonWhitePixel(objBmp, 4) + AppSettings("PaddingRight") 

            rect = New Rectangle(iLeftMostPixel, iTopMostPixel, iRightMostPixel - iLeftMostPixel, iBottomMostPixel - iTopMostPixel) 
            objNewBmp = objBmp.Clone(rect, objBmp.PixelFormat) 
            objNewBmp.Save(AppSettings("ImagePath") & Replace(oFile.Name, oFile.Extension, "_cropped" & oFile.Extension), Imaging.ImageFormat.Jpeg) 

            Console.WriteLine("Saved: " & AppSettings("ImagePath") & Replace(oFile.Name, oFile.Extension, "_cropped" & oFile.Extension)) 

            objNewBmp.Dispose() 
            objBmp.Dispose() 
        Next 
    End Sub 

    Function GetNonWhitePixel(ByVal objBmp As Bitmap, ByVal iPixelType As Integer) As Integer 
        Dim objColor As Color 

        Select Case iPixelType 
            Case 1 

                ' Top pixel 
                For y = 0 To objBmp.Height - 1 
                    For x = 0 To objBmp.Width - 1 
                        objColor = objBmp.GetPixel(x, y) 
                        If Hex(objColor.R) & Hex(objColor.G) & Hex(objColor.B) <> "FFFFFF" Then Return y 
                    Next 
                Next 

            Case 2 

                ' Left pixel 
                For x = 0 To objBmp.Width - 1 
                    For y = 0 To objBmp.Height - 1 
                        objColor = objBmp.GetPixel(x, y) 
                        If Hex(objColor.R) & Hex(objColor.G) & Hex(objColor.B) <> "FFFFFF" Then Return x 
                    Next 
                Next 

            Case 3 

                ' Bottom pixel 
                For y = objBmp.Height - 1 To 0 Step -1 
                    For x = 0 To objBmp.Width - 1 
                        objColor = objBmp.GetPixel(x, y) 
                        If Hex(objColor.R) & Hex(objColor.G) & Hex(objColor.B) <> "FFFFFF" Then Return y 
                    Next 
                Next 

            Case 4 

                ' Right pixel 
                For x = objBmp.Width - 1 To 0 Step -1 
                    For y = 0 To objBmp.Height - 1 
                        objColor = objBmp.GetPixel(x, y) 
                        If Hex(objColor.R) & Hex(objColor.G) & Hex(objColor.B) <> "FFFFFF" Then Return x 
                    Next 
                Next 

        End Select 

        ' Nothing found 
        Return 0 
    End Function 
End Module

app.config

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <appSettings> 
        <add key="ImagePath" value="C:\Path\To\My\Images\"/> 

        <add key="PaddingLeft" value="10" /> 
        <add key="PaddingRight" value="10" /> 
        <add key="PaddingBottom" value="100" /> 
        <add key="PaddingTop" value="0" /> 
    </appSettings> 
</configuration>

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Related posts

Comments

11/23/2008 9:18:21 AM

Trackback from DotNetKicks.com

Remove Surrounding White Space From An Image

DotNetKicks.com

2/20/2009 2:50:52 PM

Hi while executing this code i am getting an exception saying Out OF memory at the following line
objNewBmp = objBmp.Clone(rect, objBmp.PixelFormat)
Please guide me in this
THanks in advance
SUbbu

Subbu in

Powered by BlogEngine.NET 1.2.0.0
Theme by Mads Kristensen

About the author

My lovely wife and I at a wedding I am a web developer living in the Chicagoland area. I mainly focus on developing e-commerce applications and work with asp.net on a regular basis.


Send mail Facebook Twitter LinkedIn

Calendar

<<  February 2010  >>
MoTuWeThFrSaSu
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567

View posts in large calendar

Recent comments

Categories


    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010

    Sign in