Solved

Reading an Icon in VB.Net and maintaining original resolution

Posted on 2010-09-09
11
662 Views
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
            ico.Save(msX)
            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)
            objLogo.Save(msX)
            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

0
Comment
Question by:jdressing
  • 4
  • 3
  • 3
  • +1
11 Comments
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
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:
http://support.microsoft.com/default.aspx?scid=kb;en-us;q316563
0
 
LVL 17

Expert Comment

by:Zhaolai
ID: 33649033
Try this:

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

Open in new window

0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
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)
        ico.Save(fs)
        ico.Dispose()
        '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
        bmp.Save(outputFile)
        'PictureBox1.Image = System.Drawing.Image.FromFile(outputFile)

Open in new window

0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:jdressing
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?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
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.
0
 
LVL 38

Accepted Solution

by:
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.
'CODE TO CONVERT IMAGE TO BYTE ARRAY

        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)
        FileClose(1)
        'save to database

'CODE TO READ IMAGE DATA OUT FROM DATABASE, INTO A DATATABLE

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

Open in new window

0
 

Author Comment

by:jdressing
ID: 33653469
So does this sample have the same issue with icons?    Lower resolution / color depth?
0
 
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.
0
 

Author Comment

by:jdressing
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.
0
 
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.
0
 

Author Closing Comment

by:jdressing
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
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

770 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