Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 14:12
by Albireo
Intending to display an image with a AHK-GUI
Since I do not know how to scale an image with AHK GUI (I think it's impossible), I need to know the width and height of the image to be displayed to get structure on the entire GUI.
One way to get the size is to use IrfanView - Command line
Another way is to use gdip_all
Maybe there are better ways to do this on?
My wish is to create an object (selLogo) that contains information about the image. (eg. selLogo.name, selLogo.width, selLogo.height ...)
Tried to write a program below, but failed (in a way)
(selLogo is changed after the function call getImageSize(selLogo.name) and the selLogo.name is gone!)
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance force
#include gdip_all.ahk ; If it is not in your lib http://www.autohotkey.com/forum/topic32238.html
selLogo := []
FileSelectFile Logo, 3, C:\Users...\images, Select a imagefile, Images (*.jpg)
selLogo.name := Logo
selLogo := getImageSize(selLogo.name)
MsgBox ,, %A_ScriptName% - Row %A_LineNumber%, % "- " selLogo.Count() "`n- " selLogo.name "`n`nheight .: " selLogo.height "`nwidth .: " selLogo.width
ExitApp
getImageSize(imageFile)
{ ; https://autohotkey.com/board/topic/61076-get-image-height-property-from-file-property-details/
; lib .: gdip_all.ahk
aImage := []
If !pToken := Gdip_Startup()
{ MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
pBitmap := Gdip_CreateBitmapFromFile(imageFile)
Gdip_GetDimensions(pBitmap, width, height)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
aImage.width := width
aImage.height := height
Return % aImage
}
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 14:29
by mikeyww
GUI does scale. You can specify one dimension, and it will adjust the other.
To shrink or enlarge the image while preserving its aspect ratio, specify -1 for one of the dimensions and a positive number for the other. For example, specifying w200 h-1 would make the image 200 pixels wide and cause its height to be set automatically.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance force
SetWorkingDir %A_ScriptDir%
FileSelectFile Logo, 3, %A_ScriptDir%\.., Select a PDF-file, Images (*.jpg)
Gui Color, White
Gui Add, Picture, x50 y50 w150 h-1, %Logo%
Gui Show, w300 h300, Logo view
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 16:04
by mikeyww
Good! Here's the array version in case you like that.
SplitPath,% USERPROFILE "\Pictures\DunningKruger.jpg", FileName, DirPath,
objShell := ComObjCreate("Shell.Application")
objFolder := objShell.NameSpace(DirPath) ; set the directry path
objFolderItem := objFolder.ParseName(FileName) ; set the file name
MsgBox % objFolder.GetDetailsOf(objFolderItem, 31) ; 31 = 'width x height'
MsgBox % StrSplit(objFolder.GetDetailsOf(objFolderItem, 176), A_Space).1 ; 176 = '<width> Pixel'
MsgBox % StrSplit(objFolder.GetDetailsOf(objFolderItem, 178), A_Space).1 ; 178 = '<height> Pixel'
Here limited to width & height. BTW, the original script delivers 29 image properties (and its descriptions) for my image
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 16:19
by mikeyww
Very impressive!
I compared times of GUI vs. ComObj. Perhaps as expected, larger images favored ComObj, whereas smaller images favored GUI. On some runs, the GUI time measured was zero!
38 x 42 image: 78 ms for ComObj, 31 ms for GUI
676 x 1200 image: 78 ms for ComObj, 125 ms for GUI
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 17:09
by BoBo
I've edited the code to skip the loop that would check for 283 optional properties/items and directly access the items that are of interest instead: width&height/width/height
That way ComObj is acting instantaneously (at least for me, myself and I).
For testing, I used/downloaded this photo: https://upload.wikimedia.org/wikipedia/commons/4/41/Sunflower_from_Silesia2.jpg (2434x1697) = 31/32ms and if using SetBatchLines, -1 = 15/16ms.
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 17:23
by teadrinker
The last code doesn't actually get the picture size, it just reads metadata and shows what is wriiten there.
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 17:31
by mikeyww
Sunflower with default SetBatchLines:
ComObj: 78 ms; wins again!
GUI: 530 ms
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 17:36
by BoBo
@teadrinker Valid point. I've edited/shrank the test image. The script returned the new measurements correctly. So ...?
Re: Get the height / width of an image - to an array (object)
Posted: 01 Oct 2020, 18:18
by teadrinker
Why not? It shows what you can see in file properties. 176 and 178 doesn't show width and hight for me, they show Folder Name and Location.
Re: Get the height / width of an image - to an array (object)
img = [pathToImage]
size := imgSize(img)
x := 10
n := size.w
sum := x + n
MsgBox, x='%x%' n='%n%' sum='%sum%'
ExitApp
imgSize(img) {
SplitPath, img, fn, dir
objShell := ComObjCreate("Shell.Application")
objFolder := objShell.NameSpace(dir)
objFolderItem := objFolder.ParseName(fn)
scale := StrSplit(objFolder.GetDetailsOf(objFolderItem, 31), " x ")
Return {w: scale.1, h: scale.2}
}
Yields:
x='10' n='58' sum=''
The GUI version does not have this issue. If I hard code the GetDetailsOf with something like "58 x 9", it works. It's especially bizarre because both x and n are correct. Further: Round(n) is 0. It's like it's showing "58", but it's not really 58; it's a different character set.
What is happening with the blank sum?
Re: Get the height / width of an image - to an array (object)
I compared times of GUI vs. ComObj. Perhaps as expected, larger images favored ComObj, whereas smaller images favored GUI. On some runs, the GUI time measured was zero!
38 x 42 image: 78 ms for ComObj, 31 ms for GUI
676 x 1200 image: 78 ms for ComObj, 125 ms for GUI
... after removing the condition. So in both cases it'll return 'Breite'/'width' at 176 and 'Höhe'/'height' at 178
That's WIS + WIG .
@mikeyww - Confirmed that this sporadically has returned '0' for the same image + the output (if copied to clipboard, see my spoilered examples above) is showing/contains those characters, interestingly only for a few of its properties?!
Re: Get the height / width of an image - to an array (object)
Posted: 02 Oct 2020, 06:44
by mikeyww
Thanks for those test results and output!
I tested IsPicture(). It was initially impressive with a run time of zero ms. On further testing, it retrieved the wrong dimensions for one of my JPG files, so I'm not able to use it.