Reading an Icon in VB.Net and maintaining original resolution

Posted on 2010-09-09
Last Modified: 2012-05-10
I am using Visual Basic 2008 and working on a windows forms application.   I have tried a couple techniques to read Icons and every one of them messes up the resolution.  It reads them in, but the icon resolutions are really bad.
I have tried this:
    Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconExA" ( _
     ByVal lpszFile As String, ByVal nIconIndex As Int32, ByRef phiconLarge As IntPtr _
     , ByRef phiconSmall As IntPtr, ByVal nIcons As Int32) As Int32

            Dim icoLarge As IntPtr
            Dim icoSmall As IntPtr
            ExtractIcon(strFile, 0, icoLarge, icoSmall, 1)
            Dim ico As Icon = Icon.FromHandle(icoLarge)
            Dim msX As New MemoryStream
            rowFromTable.Item(strColName) = msX.GetBuffer
            objPic.Image = ico.ToBitmap

AND I have tried this:

            Dim msX As New MemoryStream
            Dim objLogo As System.Drawing.Icon

            objLogo = Icon.ExtractAssociatedIcon(strFile)
            rowFromTable.Item(strColName) = msX.GetBuffer
            objPic.Image = objLogo.ToBitmap

I am trying to read an ICON and save it to a table in a database and display it
on a picture image.  Any time I import it, the resolution is terrible.  The 
number of colors is terrible and the resolution are really bad

Open in new window

Question by:jdressing
  • 4
  • 3
  • 3
  • +1
LVL 29

Expert Comment

ID: 33641340
I have run into the same problem before problem is there is no encoder.

You can read more about this behavior at the following:;en-us;q316563
LVL 17

Expert Comment

ID: 33649033
Try this:

objPic.Image = System.Drawing.Image.FromFile(strFile)

Open in new window

LVL 29

Expert Comment

ID: 33649280
The problem isn't with reading the files but the way you Save(). When you use Icon.Save() there is no encoder so the result is saved in 16 colors. Then when you "read" back the file your reading back the 16 color image.
See the examples below if you want to test this.

' Bad Save()

        Dim outputFile As String = "c:\users\username\documents\icon1.bmp"

        Dim ico As Icon = Icon.FromHandle(Me.Icon.Handle)

        Dim fs As System.IO.FileStream = System.IO.File.Create(outputFile, 65536)



        'PictureBox1.Image = System.Drawing.Image.FromFile(outputFile)

        ' Good Save()

        Dim outputFile As String = "c:\users\username\documents\icon2.bmp"

        Dim ico As Icon = Icon.FromHandle(Me.Icon.Handle)

        Dim bmp As Bitmap = ico.ToBitmap


        'PictureBox1.Image = System.Drawing.Image.FromFile(outputFile)

Open in new window


Author Comment

ID: 33650593
Thank you!

So if I want to save the image to a "image" type column in a SQL table, how is the best way to save it to the table and maintain the correct resolution / number of colors?

Then also, how is the best way to read it back from from the table to an image control?
LVL 29

Expert Comment

ID: 33653300
Sorry buddy I'm not much of a database guy the only thing I can tell you is to avoid using Icon.Save().
I don't know how the image field works but you can save the bitmap bytes to the database. Then you could read back the bytes into a memory stream and call Bitmap.FromStream() or Image.FromStream().
There might be a better way to work with images in a database but that is the general idea.
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

LVL 38

Accepted Solution

Tom Beck earned 250 total points
ID: 33653446
Just an FYI, I tried saving the icon in a bitmap bytes format to a database back when this question was first posted. Same issue, it works fine for jpg, png, bmp, etc, but not for .ico. The icon coming out of the database had reduce color depth and resolution compared to the original.

        Dim curImg As System.Drawing.Image = System.Drawing.Image.FromFile(path) 'path to your image
        Dim memoryStream As System.IO.MemoryStream = New System.IO.MemoryStream
        Dim arr As Byte()
        ReDim arr(FileLen(path) - 1)
        FileOpen(1, path, OpenMode.Binary, OpenAccess.Read, OpenShare.Shared)
        FileGet(1, arr)
        'save to database


        Dim dt As New DataTable()
        Dim dtRow As DataRow        
        Dim imagedata() As Byte
        Dim imageBytedata As MemoryStream = Nothing
        ' sql connection, fill datatable...
        For Each dtRow In dt.Rows
           imagedata = dtRow.Item("imageData")
           imageBytedata = New MemoryStream(imagedata)
        'put the image into a picturebox
        Me.PictureBox1.Image = Image.FromStream(imageBytedata)

Open in new window


Author Comment

ID: 33653469
So does this sample have the same issue with icons?    Lower resolution / color depth?
LVL 38

Expert Comment

by:Tom Beck
ID: 33654307
Yes, same issues with icons, lower resolution and color depth. I posted the code to flesh out @eql1044's suggestion of saving to a database as a byte array in case you wanted to try some variation on that theme. Otherwise, it's useless.

Author Comment

ID: 33654591
Yeah, I was already storing it in the table as a byte array...  not sure why working with icons are losing their resolution/color depth.
LVL 38

Expert Comment

by:Tom Beck
ID: 33654666
Oh, did not realize that you were already storing as byte array. The code you posted does not include that.

I think @eql1044 answered the question with the link provided in 33641340.

I attempted recently to answered another question for a member who was trying to save a jpeg as an icon using VB. I spent hours on the problem, but had to give up in frustration. The question was eventually deleted without a solution. The icon file would save just fine, but when you opened it, it was at a lower resolution and rendered in just 16 colors compared to the original jpeg's 256.

Author Closing Comment

ID: 33686112
I ended up using:
To read the image from the database table:
            Dim msX As MemoryStream
            msX = New MemoryStream(objImageField)
            Return Image.FromStream(msX)

To read it from the file into database table and into a picturebox image control:
 rowFromTable.Item(strColName) = System.Drawing.Image.FromFile(strFile)
objPic.Image = System.Drawing.Image.FromFile(strFile)

These seem to maintain the correct resolution/color depth

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now