Determine image size

Windows specific forum
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Determine image size

Post by jassing »

I'm sure this is an easy one, I"m just lost..

ExtractIcon_(0,cFile,1)

How can I determine the images size and format?
What I want to do is show the file's associated 16x16 icon in a listicon...
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Determine image size

Post by IdeasVacuum »

You will need to parse all the icon images in the file (use -1 as the last value of ExtractIcon_ to get the image total).

For each image, LoadImage() followed by ImageHeight(), ImageWidth() and ImageDepth() (if necessary, not sure what you mean by 'format' - it can only be a bitmap).

That's it.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine image size

Post by jassing »

Awesome, thanks!

-j
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine image size

Post by jassing »

IdeasVacuum wrote:You will need to parse all the icon images in the file (use -1 as the last value of ExtractIcon_ to get the image total).

For each image, LoadImage() followed by ImageHeight(), ImageWidth() and ImageDepth() (if necessary, not sure what you mean by 'format' - it can only be a bitmap).

That's it.
Hm. I guess I"m confused -- how do I use LoadImage() with the handle from ExtractIcon_()?
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Determine image size

Post by IdeasVacuum »

owch, seems you can't :oops:

netmaestro posted code that could get you there: http://www.purebasic.fr/english/viewtop ... 17&start=0

....but I still can't figure out how to then collect the sizes.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine image size

Post by jassing »

Thanks -- that size bit is the important part.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Determine image size

Post by Trond »

You don't have to turn it in to a pb image to use it in the list icon gadget:

Code: Select all

File.s = "shell32.dll" ; Contains a lot of icons

IconCount = ExtractIcon_(0, File, -1)
IconMax = IconCount-1
Dim Icons.i(IconMax)
For I = 0 To IconMax
  Icons(I) = ExtractIcon_(0, File, I)
Next



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
SetGadgetAttribute(0, #PB_ListIcon_DisplayMode, #PB_ListIcon_LargeIcon)
For I = 0 To IconMax
  AddGadgetItem(0, 0, "", Icons(I))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

PS. ExtractIcon_() always returns a "large" icon (it scales it if necessary).
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Determine image size

Post by IdeasVacuum »

Trond wrote:You don't have to turn it in to a pb image to use it in the list icon gadget:
True, but when it's an exe that has several sizes of the same icon, you want to be able to choose just the one that suits your needs - to do that, you need the size.

So, perhaps the solution is to draw each icon on an invisible Window, get each Image ID of each drawing, verify each size.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Determine image size

Post by Trond »

True, but when it's an exe that has several sizes of the same icon, you want to be able to choose just the one that suits your needs - to do that, you need the size.
I know how to get the size of an api HICON easily, that's not the problem. The problem is that ExtractIcon_() returns a 32x32 icon no matter what format the icon has in the file.

To get other icon sizes, I think ExtractIconEx_() would work.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Determine image size

Post by IdeasVacuum »

.....ExtractIconEx() ala Netmaestro's code, but he is using DrawIconEx_(hdc, 10,20,small(0),0,0,0,0,#DI_NORMAL), so we still can't grab the dimensions.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine image size

Post by jassing »

What I wanted to do, and am having little success, is this

Show a combobox with some selections in it:
With all but the 1st, the icon associated with the files are shown.

All files(*.*)
MS SQL Data files (*.ldf;*.mdf)
FoxPro data files (*.dbf;*.fpt)
MS Access files (etc)

This routine needs to be somewhat generic, as the user can change what files are listed at runtime via configuration screen.

What I have no is a static list -ie: I have the icons already pulled & saved.
But if hte user enters something like:
MYDatafile (*.xyz)

I want the program to fetch the associated viewer for .xyz (not a problem) and the extract the icon & use it in the combobox next to "MyDatafile"

That's the issue -- since the api's return a handle, but the combobox wants an image#; I can't seemt o figure out how to convert them.... or load hte image as an image #.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Determine image size

Post by Trond »

but the combobox wants an image#
The combobox, just like the listicon takes a handle.

Code: Select all

#SHGFI_ADDOVERLAYS = $20
; #SHGFI_SHELLICONSIZE
; #SHGFI_SMALLICON 
; #SHGFI_LARGEICON
File.s = "c:\lorem.txt"
SHGetFileInfo_(File, 0, @info.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ADDOVERLAYS | #SHGFI_ICON | #SHGFI_SMALLICON)
Debug info\hIcon



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
ComboBoxGadget(0, 10, 10, 200, 22, #PB_ComboBox_Image)
AddGadgetItem(0, 0, "", info\hIcon)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine file's "icon"

Post by jassing »

wow; thank you. I will get the hang of this .. (at least that's what I keep telling myself)
Here's the function I ended up with to make it generic.

Code: Select all

#SHGFI_ADDOVERLAYS = $20
; #SHGFI_SHELLICONSIZE
; #SHGFI_SMALLICON 
; #SHGFI_LARGEICON

Procedure GetHandlerIcon( cExtension.s )
	Protected *memBuffer
	Protected fileInfo.SHFILEINFO
	Protected cTempFile.s, i.i=0
	Protected hndIcon = #NUL
	
	*memBuffer = AllocateMemory(1024)
	If *memBuffer 
		; Just check that we have a dot in the extension.
		If Left(cExtension,1)<>"." : cExtension = "."+cExtension : EndIf
		
		; find a unique temporary file
		Repeat
			cTempFile = "~tmp"+RSet(Str(i),5,"0")
			i+1
		Until FileSize( GetTemporaryDirectory() + cTempFile+cExtension ) = -1
		cTempFile = cTempFile+cExtension
		
		; Create a blank file -- the file's existance is required for FindExecutable()
		CloseFile(OpenFile(#PB_Any, GetTemporaryDirectory()+cTempFile ))
		
		; get the executable releated to the extension
		If FindExecutable_(cTempFile,GetTemporaryDirectory(),*memBuffer) > 32
			; fetch the information about that executable.
			SHGetFileInfo_(PeekS(*memBuffer), 0, @fileInfo, SizeOf(SHFILEINFO), #SHGFI_ADDOVERLAYS | #SHGFI_ICON | #SHGFI_SMALLICON)
			; now grab the icon's handle
		  hndIcon = fileInfo\hIcon
		EndIf
		
		; Clean up our mess
		DeleteFile(GetTemporaryDirectory()+cTempFile )
		FreeMemory(*memBuffer)
	EndIf
	ProcedureReturn hndIcon
EndProcedure



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
ComboBoxGadget(0, 10, 10, 200, 22, #PB_ComboBox_Image)
AddGadgetItem(0, 0, "*.txt", GetHandlerIcon(".txt"))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Determine image size

Post by Trond »

Your approach is wrong. You should get the icon directly from the file of the relevant type, not from the executable. An executable may contain multiple different icons. With your approach you'll always get the first. But the icon of a filetype may be one of the other icons in the executable.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Determine image size

Post by jassing »

Trond wrote:Your approach is wrong. You should get the icon directly from the file of the relevant type, not from the executable. An executable may contain multiple different icons. With your approach you'll always get the first. But the icon of a filetype may be one of the other icons in the executable.
Good point. Some things, for instance, .mdb (an MSSQL file) doesn't show a default icon -- but I know what it is; so I grab the exe -- I was focused on that specific issue and overlooked the broader view. I modified it to get the file's icon 1st, if that fails, then go to the exe, if that fails, just show a generic one...
thanks
-j
Post Reply