Click here to Skip to main content
12,998,863 members (72,154 online)
Click here to Skip to main content
Add your own
alternative version


41 bookmarked
Posted 24 Sep 2010

Image Batch Converter

, 24 Sep 2010
Rate this:
Please Sign up or sign in to vote.
Quickly resize, rename, change formats and add simple effects to multiple images.


Image Batch Converter ("IBC" from here on out) provides a quick and easy way to resize, reformat, rename, add text and apply effects to a group of images. Originally it was nothing more than a quick resizer for images imported from my cell phone, but when I decided to submit it to Code Project I added the additional features. At present it only supports a few formats (JPG, PNG, TIF, BMP AND GIF) but I'm studying up on several 3rd party libraries to add more formats.

Using the Code

There are 3 windows used in the conversion process. The main window, a text-editing window, and a results window that's displayed after the conversion. There is also a help file that explains each step involved in converting images. The code is uncomplicated - just plain vanilla GDI+.

Here's the Load event. When IBC launches, it does the following:

  • Sets the SelectedIndex property for the ComboBoxes to their value when the previous session closed (stored in My.Settings)
  • Disables the Convert button until all parameters are set
  • Checks My.Settings to see if a destination directory was saved from the last session. IBC will fetch it if it exists.
  • Updates the UI - mainly enabling/disabling controls
Private Sub main_Load(ByVal sender As System.Object,
  ByVal e As System.EventArgs) Handles MyBase.Load

  'get invalid path/file chars for user's machine
  Dim invP As Char() = Path.GetInvalidPathChars()
  Dim invC As Char() = Path.GetInvalidFileNameChars()
  For Each ch As Char In invP
  For Each ch As Char In invC

  cmb_Format.SelectedIndex = My.Settings.selFmt
  cmb_ROT.SelectedIndex = 0
  chk_TXT.Checked = My.Settings.Txt_Enabled
  tb_Convert.Enabled = False 'enable when params are set

  If Directory.Exists(My.Settings.txt_DestDir) Then
    txt_DestDir.Text = My.Settings.txt_DestDir
    txt_DestDir.Text = String.Empty
  End If

End Sub

When IBC closes, it checks to be sure the current destination directory exists. If it does, it's saved to My.Settings.

Private Sub main_FormClosing(ByVal sender As Object,
  ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

  If Directory.Exists(txt_DestDir.Text) Then
    My.Settings.txt_DestDir = txt_DestDir.Text
  End If

  My.Settings.selFmt = cmb_Format.SelectedIndex
  My.Settings.Txt_Enabled = chk_TXT.Checked

End Sub

The Conversion List


Adding images

To add images to the list, click the "+" sign in the tool bar. IBC doesn't create a collection of images. It just stores the path strings in the listView control. Selecting an image from the list displays a thumbnail in the picturebox on the right. Here's the code for the button's Click event.

Private Sub tb_Add_Click(ByVal sender As System.Object,
   ByVal e As System.EventArgs) Handles tb_Add.Click
   res = dialog_Open.ShowDialog

   If res = Windows.Forms.DialogResult.OK Then
       'string array of file names from dialog
       Dim tmp() As String = dialog_Open.FileNames

       'check against existing selections to avoid duplicates
       For l = 0 To tmp.Length - 1
         Dim tf As Boolean = False
         For zz As Integer = 0 To lvFiles.Items.Count - 1
           If lvFiles.Items.Item(zz).Text = tmp(l) Then
             tf = True 'true if duplicate found
             Exit For 'exit the checking loop
           End If
         'add image to list if no duplicate is found
         If tf = False Then
           Dim lvi As New ListViewItem(Path.GetFullPath(tmp(l)))
         End If
       lvFiles.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent)
     Catch ex As Exception
       MsgBox(ex.Message, MsgBoxStyle.Exclamation, title)
     End Try
   End If
     lvFiles.Items.Item(lvFiles.Items.Count - 1).Selected = True
   Catch ex As Exception
   End Try

 End Sub

Removing images from the list

If you change your mind about converting a particular image or group of images, click the red "X" in the tool bar. This opens a drop-down menu for removal options. You can either clear the entire list ("Clear All"), or use the checkboxes in the listview along with the "Clear Selected" option.

Here's the code for clearing selected images from the list...

Private Sub tb_ClearSel_Click(ByVal sender As System.Object,
  ByVal e As System.EventArgs) Handles tb_ClearSel.Click
    If lvFiles.CheckedItems.Count > 0 Then 'if the list is populated
      For l = lvFiles.CheckedIndices.Count - 1 To 0 Step -1 'get the checked items
        lvFiles.Items.RemoveAt(lvFiles.CheckedIndices(l)) 'remove the checked items
    End If
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation, title)
  End Try
  UpdateUI() 'update the user interface
End Sub

And to clear all images...

Private Sub tb_ClearAll_Click(ByVal sender As System.Object,
  ByVal e As System.EventArgs) Handles tb_ClearAll.Click
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation, title)
  End Try
End Sub

Destination Directory and Format


Once you've made your image selections, it's time to decide where the converted images will be written to disk, and what format if any they'll be converted to. This is done in the "Destination" tab.

Choosing a Destination Directory (required)

The first text box at the top contains the directory that will hold your converted images. Click the folder button right of the text box to open a Windows Folder dialog. The dialog's "New Folder" option is enabled so you can create a new directory if needed. The chosen directory will be displayed in the textbox. Here's the code for the folder button's Click event.

Private Sub btn_DestDir_Click(ByVal sender As System.Object,
    ByVal e As System.EventArgs) Handles btn_DestDir.Click
  'A "\" is added to the end of the path if
  'one isn't already there. It was either append
  'it here or prepend it to the file names.

    res = dialog_Folder.ShowDialog
    If res = Windows.Forms.DialogResult.OK Then
      myStr = dialog_Folder.SelectedPath
      If Not myStr.EndsWith("\") Then
        myStr &= "\"
      End If
      txt_DestDir.Text = myStr

    End If
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation, title)
  End Try
End Sub

Choosing a Base File Name (optional)

In the second text box, you can type a base file name that will be applied to all converted images with a counter. For example, if you type "MyConvertedImages" with .jpg as the selected format, your file names will be:

  • "MyConvertedImages_1.jpg"
  • "MyConvertedImages_2.jpg"

... and so on. To retain the original file names, just leave this text box empty. If ANY legal text is in this text box, it'll automatically use it for a base file name. It attempts to block characters that Windows doesn't recognize as legal path characters. I say "attempts" here because there is a caveat in that regard in the documentation regarding the method I used (Path.GetInvalidPathChars) to build the collection of characters to watch for. My guess is it's very close to 100% accuracy.

Overwrite Rules (required)

IBC provides three "Overwrite Rules" to protect existing files. They are:

Overwrite Automatically
IBC overwrites any file of the same name and format without input from the user.
Ask Before Overwrite
A Windows message box will pop up and ask if you're sure you wish to overwrite an existing file.
Do Not Overwrite
All existing files are skipped (not overwritten) with no input from the user.

Select the appropriate rule by clicking one of the RadioButtons in the "Overwrite Rules" Groupbox.

Selecting a Destination Format (optional)

If you wish to save all selected images to a single format (.jpg, .png, etc), first make sure the "Use Selected Format" checkbox is checked. This enables the format controls. In the Destination Format GroupBox you can choose which image format your converted images will be saved in. Select one from the drop down list. The default is .jpg. If .jpg is selected, the nearby track bar allows you to set the quality / compression of the images. If you leave the format checkbox unchecked, each image will be saved in its original format.

Resizing and Image Effects


Resizing (optional)

IBC provides three methods of resizing images, and the resize tools are located in a small tab control. For resizing to occur, you must check the "Resize Images" CheckBox just above the tab control. To select a resize method, click the appropriate tab. The resizing methods are:

Single Dimension (1st tab)
Allows user to enter a single numeric value and designate whether it represents width or height via RadioButtons. The other dimension is scaled automatically to maintain aspect ratio.
Percentage (2nd tab)
Provides a trackbar with a range of 10 to 300 percent for upsizing and downsizing images with aspect ratio maintained.
Absolute Dimension (3rd tab)
User enters both a width and height. All images are sized to these dimensions without regard to aspect ratio.

Image Transformations (optional)
IBC doesn't support complex transformations, but it does allow you to flip, rotate and convert images to grayscale. Just select the appropriate check boxes for vertical and/or horizontal flip, grayscale, and choose rotation degree from the drop-down list.

NOTE: If you add text to a grayscale image, the text color is retained. So, you can have a grayscale image with chatreuse text if you so desire. Also, text alignment is not affected by flip/rotate because it's drawn after everything else happens.

Using the Text Tool


This feature, located in the Resizing and Effects tab, allows you to add a single line of text to all converted images. You can choose any font, style and color your computer supports. Note that you won't be able to add text until all other options are either set or disabled. This is because IBC provides a post-conversion preview of all the images while the text tool is open, so you can see how the text will look on each image. This is also a good way to preview your images even if you don't intend to add any text.

First, be sure the "Use Text" CheckBox in the "Add Text" GroupBox is selected. If the "Edit Text" button just below it is enabled, you can open the text tool. Click the button to open the tool. The text tool is a Windows dialog. It'll size itself to fill your screen when it opens to make it easier to view larger images. You can resize it if you want to.

Explanation of the Tool Bar Buttons

From left to right, the tool bar buttons are:
Save and Return to Main Window
Saves the text and formatting and closes the text tool
You MUST click the Save button for the text to appear in your images.
If you make changes to existing text but click the Cancel button (below), you will lose your changes and the previous text, if there is any, will be drawn instead.
Cancel and Return to Main Window
Discards changes to text and closes the text tool
Set Font
Set the font (all the text is in one font and style)
Set Text Color
Sets the color. The text input area is always black on white. The color changes only in the preview.
Text Alignment Menu
Opens two drop-down menus (horizontal & vertical) to set how the text is aligned on the image.
Horizontal options are: Left, Right, and Center
Vertical options are: Top, Middle and Bottom
For example, choosing Left and Bottom from the menus places the text in the lower left corner.
Navigation Buttons for Image List (First, Previous, Next, Last) and an "x of x" display
Works similar to a slide show. This allows you to page through all the images to see how your text will appear. Be sure that your text isn't too wide for any of the images.
TrackBar for Setting Opacity / Transparency of the Text
Slide right to increase opacity, left to decrease it.
One use for this is the creation of simplistic watermarks for your images.

Entering Text

Type in the TextBox just below the tool bar. The currently selected image (previewed below the TextBox) updates as you type. There is no need to click a "Preview Button" or open another window to see how the text will look. Same goes for changing the font, color and opacity. Click back and forth via the tool bar arrows to view multiple images.

The StatusBar at the bottom of the window shows the path and file name of the currently selected image.

Here's the text tool's Load event handler. It creates a collection of type Image and loads the images. Then it converts them, all except the text. The Back and Next buttons in the tool bar allow you to page through the images. No images are saved to disk at this point.

Private Sub dialog_Text_Load(ByVal sender As System.Object,
  ByVal e As System.EventArgs) Handles MyBase.Load
  'size dialog to fill screen (you can also resize it manually)
  Dim wr As Rectangle = Screen.PrimaryScreen.WorkingArea
  Me.Size = New System.Drawing.Size(wr.Width - 10, wr.Height - 10)
  Me.Location = New System.Drawing.Point(5, 5)

  Me.Cursor = Cursors.WaitCursor
  'load images
  'if resize or grayscale options are enabled,
  'preview images will reflect those options
  For Each lvi As ListViewItem In main.lvFiles.Items
      'this function checks options in main window and
      'applies whatever is enabled before adding to the
      'collection. Note that format conversions are ignored
      'so you won't see JPEG compression results here.

      Dim newBMP As Bitmap = PrepPreviewImage(Image.FromFile(lvi.Text))

    Catch ex As Exception
      MsgBox(ex.ToString, MsgBoxStyle.Exclamation, main.title)
    End Try

  SourceImage = imgList(0) 'loads initial img from list
  index = 0 : imgCnt = main.lvFiles.Items.Count 'for nav buttons
  txt_Text.Font = My.Settings.TxtFont
  sldr_Opc.Value = My.Settings.Opacity
  lbl_Opc.Text = sldr_Opc.Value.ToString
  BrushColor = My.Settings.txt_Color 'triggers creation of new brush when changed
  TextBrush = New SolidBrush(My.Settings.txt_Color) 'brush to draw text
  txt_Text.Text = My.Settings.TxtString 'text to draw

  'get text alignment
  'cumbersome code - needs improvement
  'sets alignment menu items and text aligment properties
  For Each tsmi As ToolStripMenuItem In tb_HAlign.DropDownItems
    tsmi.Checked = False
  For Each tsmi As ToolStripMenuItem In tb_VAlign.DropDownItems
    tsmi.Checked = False
  Select Case My.Settings.alignH
    Case 1
      alignh_Left.Checked = True
      HTextAlign = TextAlignH.Left
    Case 2
      alignh_Center.Checked = True
      HTextAlign = TextAlignH.Center
    Case 3
      alignh_Right.Checked = True
      HTextAlign = TextAlignH.Right
  End Select

  Select Case My.Settings.alignV
    Case 1
      alignV_Top.Checked = True
      VTextAlign = TextAlignV.Top
    Case 2
      alignv_Middle.Checked = True
      VTextAlign = TextAlignV.Middle
    Case 3
      alignv_Bottom.Checked = True
      VTextAlign = TextAlignV.Bottom
  End Select
  '-----------------end textalign-------------------

  Me.Cursor = Cursors.Default

End Sub

Any time you take an action that changes the preview image (typing, changing font or color, or alignment), the image of course must be updated. So, the textbox's TextChanged event, and the Click events for the Font, Color and Alignment menu items call the UpdateImage Sub.

Private Sub UpdateImage()
  'any time a redraw operation is needed

    'default in case color/brush is not set
    If TextBrush Is Nothing Then
      BrushColor = Color.FromArgb(sldr_Opc.Value, 240, 240, 240)
      TextBrush = New SolidBrush(BrushColor)
    End If

    'reset display image (img)
    img = New Bitmap(SourceImage.Width, SourceImage.Height)
    Dim g As Graphics = Graphics.FromImage(img)
    g.DrawImage(SourceImage, 0, 0)

    If txt_Text.TextLength > 0 Then 'if text is present, draw it

      'measure the string (for alignment pruposes)
      rectSize = g.MeasureString(TextForImages, txt_Text.Font, New PointF(0, 0),

      'set x & y values according to alignment options
      Select Case HTextAlign
        Case TextAlignH.Center
          x = (img.Width / 2) - (rectSize.Width / 2)
        Case TextAlignH.Left
          x = 2
        Case TextAlignH.Right
          x = (img.Width - rectSize.Width) - 2
      End Select

      Select Case VTextAlign
        Case TextAlignV.Bottom
          y = (img.Height - rectSize.Height) - 2
        Case TextAlignV.Middle
          y = (img.Height / 2) - (rectSize.Height / 2)
        Case TextAlignV.Top
          y = 2
      End Select

      'draw text on display image
      Dim dPoint As New Point(x, y)
      g.TextRenderingHint = TextRenderingHint.AntiAlias
      g.DrawString(TextForImages, txt_Text.Font, TextBrush, dPoint,
    End If

    'display image in picbox
    picbox.Image = img

  Catch ex As Exception
  End Try
End Sub


Converting the Images

The Convert button will remain disabled until all necessary options are set (destination directory, etc). Once you've set all the required options, click the Convert ("Gear") button in the tool bar to start the process. Once the process is complete a dialog will open that details the results.

Possible results are:

  • SUCCESS, if the image converted
  • FAILED if it did not convert
  • FILE NOT FOUND (lets face it, sometimes files disappear)
  • SKIPPED if prevented by an overwrite rule.

When you close the results dialog, the destination directory will open so you can see the images.

NOTE: If an image file is corrupt and somehow still made it into the list, in all likelihood you'll get a FILE NOT FOUND or FAILED message in the results dialog.

Here's the code for the Convert button's click event:

Private Sub tb_Convert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles tb_Convert.Click
    'reset results dialog and file name counter for new conversion
    nameCnt = 0
    'loop through the selected files
    'the list doesn't store the images, just the 
    'paths to the images.
    For l = 0 To lvFiles.Items.Count - 1
        fileNameStr = CreateFileName() 'the new path for the converted image
        'overwrite rules...
        'checks to see which overwrite option is chosen
        'this is where messages in results dialog are created
        'if a file already exists, acts appropriately according
        'to the selected overwrite rule
        If File.Exists(fileNameStr) Then
          If rad_OvrNO.Checked Then
            dialog_Results.lb_Results.Items.Add(fileNameStr & " : SKIPPED - No Overwrite")
            Exit Try
          ElseIf rad_OvrPrompt.Checked Then
            msg = "The image," & Chr(10) _
            & fileNameStr & Chr(10) _
            & "already exists. Overwrite?"
            res = MsgBox(msg, MsgBoxStyle.YesNo, title)
            If res = Windows.Forms.DialogResult.No Then
                  fileNameStr & " : SKIPPED - No Overwrite")
              Exit Try
            End If
          ElseIf rad_OvrAuto.Checked Then
            'no action necessary
          End If 'radio buttons
        End If 'File.Exists
        'create a new image from the current original
        tmpBMP = System.Drawing.Image.FromFile(lvFiles.Items.Item(l).Text)
        'get the selected extension from the format combobox
        Dim destExt As String = cmb_Format.SelectedItem.ToString
        'the selected extension from above decides the 
        'ImageFormat object returned from SetFormat()
        'set extension according to state of chk_Reformat
        If chk_Reformat.Checked Then
          imgFormat = SetFormat(destExt)
          imgFormat = SetFormat(Path.GetExtension(lvFiles.Items.Item(l).Text))
        End If
        Dim imgSize As Size = ResizeImage(tmpBMP.Size)
        Dim newBMP As New Bitmap(imgSize.Width, imgSize.Height)
        Dim g As Graphics = Graphics.FromImage(newBMP)
        g.DrawImage(tmpBMP, New Rectangle(0, 0, imgSize.Width, imgSize.Height))
        'image f/x
        If chk_FlipH.Checked Then
        End If
        If chk_FlipV.Checked Then
        End If
        If cmb_ROT.SelectedIndex > 0 Then
          Select Case cmb_ROT.SelectedIndex
            Case 1
            Case 2
            Case 3
          End Select
        End If
        If chk_Gray.Checked Then
          newBMP = GrayScale(newBMP)
        End If
        'draw text (does the math here for image alignment - based on image
        'size and string size)
        'size of text is stored in My.Settings
        If chk_TXT.Checked AndAlso My.Settings.TxtString.Length > 0 Then
          Dim sb As New SolidBrush(My.Settings.txt_Color)
          Select Case My.Settings.alignH
            Case 1
              x = 2
            Case 2
              x = (newBMP.Width / 2) - (My.Settings.txt_Rsize.Width / 2)
            Case 3
              x = (newBMP.Width - My.Settings.txt_Rsize.Width) - 2
          End Select
          Select Case My.Settings.alignV
            Case 1
              y = 2
            Case 2
              y = (newBMP.Height / 2) - (My.Settings.txt_Rsize.Height / 2)
            Case 3
              y = (newBMP.Height - My.Settings.txt_Rsize.Height) - 2
          End Select
          Dim tgr As Graphics = Graphics.FromImage(newBMP)
          tgr.DrawString(My.Settings.TxtString, My.Settings.TxtFont, sb, x, y,
          'dialog_Preview.PictureBox1.Image = newBMP
        End If
        'save image
        If imgFormat.Equals(ImageFormat.Jpeg) Then
          Dim jgpEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
          Dim myEncoder As Encoder = Encoder.Quality
          Dim myEncoderParameters As New EncoderParameters(1)
          Dim myEncoderParameter As New EncoderParameter(myEncoder, sldr_Quality.Value)
          myEncoderParameters.Param(0) = myEncoderParameter
          newBMP.Save(fileNameStr, jgpEncoder, myEncoderParameters)
          newBMP.Save(fileNameStr, imgFormat)
        End If
        dialog_Results.lb_Results.Items.Add(fileNameStr & " : SUCCESS!")
      Catch ex As Exception
        If Not File.Exists(fileNameStr) Then
          dialog_Results.lb_Results.Items.Add(fileNameStr & " : FILE NOT FOUND")
          dialog_Results.lb_Results.Items.Add(fileNameStr & " : ERROR")
        End If
      End Try
    Next l
    'Open the destination folder
    Catch ex As Exception
      MsgBox("Could not open destination directory.", MsgBoxStyle.Exclamation, title)
    End Try
  End Sub

The Convert sub calls several functions to complete the operation.

If you've selected a resize option, this function takes the size of each original (ByVal s As Size) and applies that option. It then returns the new size. If you have chosen not to resize, it returns the original size back to the Convert sub.

Friend Function ResizeImage(ByVal s As Size)

  'If ResizeImage checkbox is unchecked, use existing size
  If Not chk_Resize.Checked Then
    Return s
  End If

  'resize according to selected option in tab control
    Select Case tab_Resize.SelectedIndex
      Case 0  'one dimension
        If rad_Width.Checked Then
          pctW = Val(txt_Dim.Text) / s.Width
          newW = Val(txt_Dim.Text)
          newH = s.Height * pctW

        ElseIf rad_Height.Checked Then
          pctH = Val(txt_Dim.Text) / s.Height
          newW = s.Width * pctH
          newH = Val(txt_Dim.Text)
        End If

      Case 1  'percentage
        pctSldr = sldr_Size.Value / 100
        newW = s.Width * pctSldr
        newH = s.Height * pctSldr

      Case 2  'absolute size
        newW = Val(txt_AbsWidth.Text)
        newH = Val(txt_AbsHeight.Text)
    End Select

  Catch ex As Exception
    'returning a zero size will trigger a warning in the convert sub
    Return New Size(0, 0)
  End Try

  Return New Size(newW, newH)
End Function

If you've selected a common format for all converted images...

Private Function SetFormat(ByVal ext As String) As ImageFormat
  'if changing format, this returns the correct ImageFormat object
  'based upon the chosen extension in the format combobox

  Select Case ext
    Case ".jpg"
      Return ImageFormat.Jpeg

    Case ".gif"
      Return ImageFormat.Gif

    Case ".bmp"
      Return ImageFormat.Bmp

    Case ".png"
      Return ImageFormat.Png

    Case ".tif"
      Return ImageFormat.Tiff

    Case Else
      MsgBox(msg, MsgBoxStyle.Information, "Error")
      Return Nothing
  End Select
End Function

This creates a new path and file name for each image...

Private Function CreateFileName()
  Dim fStr As String = String.Empty
  'get directory path

  'fStr is the text in the destination directory textbox
  fStr = txt_DestDir.Text
  If Not fStr.EndsWith("\") Then
    fStr &= "\"
  End If

  'nameCnt is the variable that increments new file names (myFile_1.jpg, myFile_2.jpg...)
  If txt_FileName.TextLength > 0 Then
    'if creating new file names...
    nameCnt += 1
    fStr &= txt_FileName.Text & "_" & nameCnt.ToString
    'if using original file names...
    fStr &= Path.GetFileNameWithoutExtension(lvFiles.Items.Item(l).Text)
  End If

  If chk_Reformat.Checked Then
    'if changing formats...
    fStr &= cmb_Format.SelectedItem.ToString
    'if not changing formats...
    fStr &= Path.GetExtension(lvFiles.Items.Item(l).Text)
  End If
  Return fStr
End Function

If you're converting to JPG, this returns the encoder so you can set compression

Private Function GetEncoder(ByVal format As ImageFormat) As ImageCodecInfo
  'when saving to JPEG, gets the encoder so you can set compression
  Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
  For Each codec As ImageCodecInfo In codecs
    If codec.MimeType.Equals("image/jpeg") Then
      Return codec
    End If
  Next codec
  Return Nothing
End Function

And if you're converting to grayscale...

Friend Function GrayScale(ByVal img As Image)
  'this function based on code from
  '(because his works a lot better than mine did)

    Dim bm As Bitmap = New Bitmap(img.Width, img.Height)
    Dim g As Graphics = Graphics.FromImage(bm)

    Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
               {New Single() {0.3, 0.3, 0.3, 0, 0}, _
              New Single() {0.59, 0.59, 0.59, 0, 0}, _
              New Single() {0.11, 0.11, 0.11, 0, 0}, _
              New Single() {0, 0, 0, 1, 0}, _
              New Single() {0, 0, 0, 0, 1}})

    Dim ia As ImageAttributes = New ImageAttributes()
    g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width,
        img.Height, GraphicsUnit.Pixel, ia)
    Return bm

  Catch ex As Exception
    MsgBox(ex.ToString, MsgBoxStyle.Exclamation, title)
    Return Nothing
  End Try
End Function

That's about it. The conversion process runs pretty quickly even with a large number of images. If you find any bugs, please do post a message here and I'll crush it as soon as time allows. I hope you find IBC useful and enjoyable.

Points of Interest

I spent some time stressing over how best to create a help file to be included in the project. I ended up creating simple HTML docs and storing them in My.Resources. The help app consists of a SplitContainer with a WebBrowser control in the right panel to display the text. The left panel contains a TableLayoutPanel with LinkLabels representing each topic in the help file. Click the link and the corresponding HTML file is written to the browser's DocumentText property. Can't call it a perfect solution, but it has the virtue of being easy on the eyes. I'd enjoy knowing what others think of it.


Initial release uploaded 09.24.2010


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Alan Burkhart
United States United States
I'm not an IT guy. Programming has been a hobby for me (and occasionally useful) ever since a sister in-law introduced me to a TI-99 4/A about a million years ago.

The creative challenge is relaxing and enjoyable. As such, I'd never mess up a fun hobby by doing it for a living.

Now, if I can just get Code Project to add "Truck Driver" to the list of job titles in the profiles...

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
manoj kumar choubey28-Feb-12 22:35
membermanoj kumar choubey28-Feb-12 22:35 
GeneralNice job Pin
Hardy Wang22-Oct-10 3:09
memberHardy Wang22-Oct-10 3:09 
GeneralRe: Nice job Pin
Alan Burkhart22-Oct-10 14:44
memberAlan Burkhart22-Oct-10 14:44 
QuestionRe: Nice job Pin
jeroen van dael28-Oct-10 23:41
memberjeroen van dael28-Oct-10 23:41 
AnswerRe: Nice job Pin
Alan Burkhart29-Oct-10 2:27
memberAlan Burkhart29-Oct-10 2:27 
GeneralMy vote of 5 Pin
db_cooper195018-Oct-10 6:18
memberdb_cooper195018-Oct-10 6:18 
Generalnice article Pin
CIDev29-Sep-10 6:22
memberCIDev29-Sep-10 6:22 
GeneralRe: nice article Pin
Alan Burkhart29-Sep-10 10:57
memberAlan Burkhart29-Sep-10 10:57 
GeneralNice Pin
Jamal Alqabandi28-Sep-10 1:58
memberJamal Alqabandi28-Sep-10 1:58 
GeneralRe: Nice Pin
Alan Burkhart29-Sep-10 11:03
memberAlan Burkhart29-Sep-10 11:03 
GeneralLooks nice! Pin
Shane Story27-Sep-10 8:50
memberShane Story27-Sep-10 8:50 
GeneralRe: Looks nice! Pin
Alan Burkhart27-Sep-10 8:54
memberAlan Burkhart27-Sep-10 8:54 
Questionhow about Pin
xoox27-Sep-10 3:10
memberxoox27-Sep-10 3:10 
AnswerRe: how about Pin
Alan Burkhart27-Sep-10 3:26
memberAlan Burkhart27-Sep-10 3:26 
GeneralMy vote of 5 Pin
HoyaSaxa9325-Sep-10 3:33
memberHoyaSaxa9325-Sep-10 3:33 
GeneralRe: My vote of 5 Pin
Alan Burkhart27-Sep-10 8:58
memberAlan Burkhart27-Sep-10 8:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170622.1 | Last Updated 24 Sep 2010
Article Copyright 2010 by Alan Burkhart
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid