Query Image Properties.

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Query Image Properties.

Post by MigrationUser »

11 Jan 2018 17:41
Dheath

Query Image Properties.

Hello again, does anyone know if there is a way to query the image "details" displayed in the image's "properties" GUI? I am specifically interested in the "Dimension" value of .jpg files.

"Wmic datafile get" only seems to provide the generic file details, not those specific to the file type, but that's all I've been able to find without using Powershell or 3rd party tools is to query. I don't mind using Powershell if necessary, it just seems like there should be a way to do this in CMD.

----------------------------

#2 11 Jan 2018 23:53
Simon Sheppard

I think you have to use a 3rd party tool.

ImageMagick is small and free and can do this:

magick identify rose.jpg
rose.jpg JPEG 70x46 70x46+0+0 8-bit sRGB 2.36KB 0.000u 0:00.000

https://www.imagemagick.org/script/comm ... -tools.php

----------------------------

#3 12 Jan 2018 18:32
Dheath

Ok, thanks a lot!

I guess Explorer must use Powershell to access those details, but ImageMagick should work fine for me. :)

----------------------------
#4 21 Jan 2018 16:35
Clydero

I haven't had any problems with ImageMagick. How long have you been using it, Dheath?

----------------------------
#5 22 Jan 2018 00:37
Dheath

I've heard the name before but this is my first time actually using it. I'm not having any trouble though, identify.exe is working fine.

It does seem like the file-type specific file properties can be queried through PowerShell somehow if anyone wants to do that, but I'm not really familiar with PowerShell and ImageMagick seems worth getting used to.

----------------------------
#6 10 Feb 2018 11:55
Sponge Belly

The code below is based on tooltipInfo.bat by npocmaka except that I used ExtendedProperty() instead of GetDetailsOf().

Code: Select all

@if (@X==@Y) @then
:: Batch
   @echo off & setLocal enableExtensions disableDelayedExpansion
(call;) %= sets errorLevel to 0 =%
   
(
    for /f "tokens=1,2 delims=x " %%X in ('
        cscript //E:JScript //nologo "%~dpf0" "%~dpf1" %2
    ') do (set "width=%%X" & set "height=%%Y") %= for /f =%
) || goto end %= cond exec =%
echo("%~nx1": width=%width% height=%height%

:end - exit program with appropriate errorLevel
endLocal & goto :EOF
   
@end // JScript

// objects
var FSOObj = WScript.CreateObject("Scripting.FileSystemObject"),
    objShell = WScript.CreateObject("Shell.Application");

var ARGS = WScript.Arguments;
if (ARGS.length != 1) {
WScript.StdErr.WriteLine("too many arguments");
    WScript.Quit(1);
} else if (ARGS.Item(0) == "") {
    WScript.StdErr.WriteLine("filename expected");
    WScript.Quit(1);
} // if

ExistsItem = function (path) {
    return FSOObj.FolderExists(path) || FSOObj.FileExists(path);
} // ExistsItem

getFullPath = function (path) {
    return FSOObj.GetAbsolutePathName(path);
} // getFullPath

getParent = function(path) {
    var splitted = path.split("\\"), result = "";

    for (var s=0; s<splitted.length-1; s++) {
        if (s == 0) {
            result = splitted[s];
        } else {
            result = result + "\\" + splitted[s];
        } // if
    } // for

    return result;
} // getParent

getName = function(path) {
    var splitted = path.split("\\");
    return splitted[splitted.length-1];
} // getName

var filename = ARGS.Item(0),
    shortFilename = filename.replace(/^.+\\/, '');
if (!ExistsItem(filename)) {
   WScript.StdErr.WriteLine('"' + shortFilename + '" does not exist');
    WScript.Quit(1);
} // if

var fullFilename=getFullPath(filename), namespace=getParent(fullFilename),
    name=getName(fullFilename), objFolder=objShell.NameSpace(namespace),
    objItem;
if (objFolder != null) {
    objItem=objFolder.ParseName(name);
    if (objItem.ExtendedProperty("Dimensions") != null) {
        WScript.Echo(objItem.ExtendedProperty("Dimensions").slice(1, -1));
    } else {
        WScript.StdErr.WriteLine('"' + shortFilename +
            '" is not an image file');
        WScript.Quit(1);
    } // if 2
} // if 1

WScript.Quit(0);
Edit: Improved error handling.

Last edited by Sponge Belly (02 Mar 2018 17:46)

----------------------------

#7 11 Feb 2018 15:48
Pyprohly

Nice!

I wonder if there’s a way to get a list of the valid properties for the ExtendedProperty method. It seems that it’s just by luck that “Dimensions” worked here because many of the other properties don’t, such as “Width” and “Height”, unlike in GetDetailsOf.

Here’s a demo of a way to see a comparison between GetDetailsOf and ExtendedProperty using header names derived from GetDetailsOf. For ExtendedProperty, “Dimensions” is one of the very few fields that are filled for a .jpg.

Code: Select all

GetFolderItemProperties.ps1

$file = 'C:\Users\Pyprohly\Desktop\test2\IMG-12.jpg'

$folderPath = Split-Path -Parent $file
$fileName = Split-Path -Leaf $file

$shellApp = New-Object -ComObject Shell.Application
$folder = $shellApp.NameSpace($folderPath)
$folderItem = $folder.ParseName($fileName)

0..320 | % {
	'Column,Header,Value'
} {
	$(if ($v = $folder.GetDetailsOf($folderItem, $_)) {'##### '}) +
	"$_," + $folder.GetDetailsOf($null, $_) + ',' + $v
} | Out-File GetDetailsOf_details.txt

0..320 | % {
	'Column,Header,Value'
} {
	$(if ($v = $folderItem.ExtendedProperty($folder.GetDetailsOf($null, $_))) {'##### '}) +
	"$_," + $folder.GetDetailsOf($null, $_) + ',' + $v
} | Out-File ExtendedProperty_details.txt

I’ve put together a batch script using that alternate method mentioned by npocmaka_, using that WIA.ImageFile COM object. This convenient batch function can be used to get an image’s dimensions.

GetImageDimensions.bat

Code: Select all

@echo off

set "image_file=C:\Users\Pyprohly\Desktop\test2\IMG-12.jpg"

goto :main

:get_image_file_properties ImageFilePath [OutVar]
setlocal
	set "filename=%~1"

	for /f "tokens=1-13 delims=:" %%A in ('
		mshta vbscript:code^(close^(Execute^("Set o=CreateObject(""WIA.ImageFile""):o.LoadFile(""%filename%""):CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write(Join(Array(o.FormatID,o.FileExtension,o.Width,o.Height,o.HorizontalResolution,o.VerticalResolution,o.PixelDepth,o.IsIndexedPixelFormat,o.IsAlphaPixelFormat,o.IsExtendedPixelFormat,o.IsAnimated,o.FrameCount,o.ActiveFrame),"":""))"^)^)^) ^| more
	') do (
		set "FormatID=%%~A"
		set "FileExtension=%%~B"
		set "Width=%%~C"
		set "Height=%%~D"
		set "HorizontalResolution=%%~E"
		set "VerticalResolution=%%~F"
		set "PixelDepth=%%~G"
		set "IsIndexedPixelFormat=%%~H"
		set "IsAlphaPixelFormat=%%~I"
		set "IsExtendedPixelFormat=%%~J"
		set "IsAnimated=%%~K"
		set "FrameCount=%%~L"
		set "ActiveFrame=%%~M"
	)

	set "[="
	set "]="
	if not "%~2"=="" (
		set "[=%~2["
		set "]=]"
	)
endlocal & (
	set "%[%FormatID%]%=%FormatID%"
	set "%[%FileExtension%]%=%FileExtension%"
	set "%[%Width%]%=%Width%"
	set "%[%Height%]%=%Height%"
	set "%[%HorizontalResolution%]%=%HorizontalResolution%"
	set "%[%VerticalResolution%]%=%VerticalResolution%"
	set "%[%PixelDepth%]%=%PixelDepth%"
	set "%[%IsIndexedPixelFormat%]%=%IsIndexedPixelFormat%"
	set "%[%IsAlphaPixelFormat%]%=%IsAlphaPixelFormat%"
	set "%[%IsExtendedPixelFormat%]%=%IsExtendedPixelFormat%"
	set "%[%IsAnimated%]%=%IsAnimated%"
	set "%[%FrameCount%]%=%FrameCount%"
	set "%[%ActiveFrame%]%=%ActiveFrame%"
)
goto :eof

:main
call :get_image_file_properties "%image_file%" Image

echo Dimensions: %Image[Width]% x %Image[Height]%
Last edited by Pyprohly (11 Feb 2018 15:48)

----------------------------

#8 21 Feb 2018 16:12
npocmaka

Here's the list of the properties:

Code: Select all

-1 
0 Name: 
1 Size: 
2 Item type: 
3 Date modified: 
4 Date created: 
5 Date accessed: 
6 Attributes: 
7 Offline status: 
8 Offline availability: 
9 Perceived type: 
10 Owner: 
11 Kind: 
12 Date taken: 
13 Contributing artists: 
14 Album: 
15 Year: 
16 Genre: 
17 Conductors: 
18 Tags: 
19 Rating: Unrated
20 Authors: 
21 Title: 
22 Subject: 
23 Categories: 
24 Comments: 
25 Copyright: 
26 #: 
27 Length:
28 Bit rate: 
29 Protected: 
30 Camera model: 
31 Dimensions: 
32 Camera maker: 
33 Company: 
34 File description: 
35 Program name: 
36 Duration: 
37 Is online: 
38 Is recurring: 
39 Location: 
40 Optional attendee addresses: 
41 Optional attendees: 
42 Organizer address: 
43 Organizer name: 
44 Reminder time: 
45 Required attendee addresses: 
46 Required attendees: 
47 Resources: 
48 Meeting status: 
49 Free/busy status: 
50 Total size: 
51 Account name: 
52 Task status: 
53 Computer: 
54 Anniversary: 
55 Assistant's name: 
56 Assistant's phone: 
57 Birthday: 
58 Business address: 
59 Business city: 
60 Business country/region: 
61 Business P.O. box: 
62 Business postal code: 
63 Business state or province: 
64 Business street: 
65 Business fax: 
66 Business home page: 
67 Business phone: 
68 Callback number: 
69 Car phone: 
70 Children: 
71 Company main phone: 
72 Department: 
73 E-mail address: 
74 E-mail2: 
75 E-mail3: 
76 E-mail list: 
77 E-mail display name: 
78 File as: 
79 First name: 
80 Full name: 
81 Gender: 
82 Given name: 
83 Hobbies: 
84 Home address: 
85 Home city: 
86 Home country/region: 
87 Home P.O. box: 
88 Home postal code: 
89 Home state or province: 
90 Home street: 
91 Home fax: 
92 Home phone: 
93 IM addresses: 
94 Initials: 
95 Job title: 
96 Label: 
97 Last name: 
98 Mailing address: 
99 Middle name: 
100 Cell phone: 
101 Nickname: 
102 Office location: 
103 Other address: 
104 Other city: 
105 Other country/region: 
106 Other P.O. box: 
107 Other postal code: 
108 Other state or province: 
109 Other street: 
110 Pager: 
111 Personal title: 
112 City: 
113 Country/region: 
114 P.O. box: 
115 Postal code: 
116 State or province: 
117 Street: 
118 Primary e-mail: 
119 Primary phone: 
120 Profession: 
121 Spouse/Partner: 
122 Suffix: 
123 TTY/TTD phone: 
124 Telex: 
125 Webpage: 
126 Content status: 
127 Content type: 
128 Date acquired: 
129 Date archived: 
130 Date completed: 
131 Device category: 
132 Connected: 
133 Discovery method: 
134 Friendly name: 
135 Local computer: 
136 Manufacturer: 
137 Model: 
138 Paired: 
139 Classification: 
140 Status: 
141 Client ID: 
142 Contributors: 
143 Content created: 
144 Last printed: 
145 Date last saved: 
146 Division: 
147 Document ID: 
148 Pages: 
149 Slides: 
150 Total editing time: 
151 Word count: 
152 Due date: 
153 End date: 
154 File count: 
155 Filename:
156 File version: 
157 Flag color: 
158 Flag status: 
159 Space free: 
160 Bit depth: 
161 Horizontal resolution: 
162 Width: 
163 Vertical resolution: 
164 Height: 
165 Importance: 
166 Is attachment: 
167 Is deleted: 
168 Encryption status: 
169 Has flag: 
170 Is completed: 
171 Incomplete: 
172 Read status: 
173 Shared: No
174 Creators: 
175 Date: 
176 Folder name:
177 Folder path: 
178 Folder: 
179 Participants: 
180 Path: 
181 By location: 
182 Type: AVCHD Video
183 Contact names: 
184 Entry type: 
185 Language: 
186 Date visited: 
187 Description: 
188 Link status: 
189 Link target: 
190 URL: 
191 Media created: 
192 Date released: 
193 Encoded by: 
194 Producers: 
195 Publisher: 
196 Subtitle: 
197 User web URL: 
198 Writers: 
199 Attachments: 
200 Bcc addresses: 
201 Bcc: 
202 Cc addresses: 
203 Cc: 
204 Conversation ID: 
205 Date received: 
206 Date sent: 
207 From addresses: 
208 From: 
209 Has attachments: 
210 Sender address: 
211 Sender name: 
212 Store: 
213 To addresses: 
214 To do title: 
215 To: 
216 Mileage: 
217 Album artist: 
218 Album ID: 
219 Beats-per-minute: 
220 Composers: 
221 Initial key: 
222 Part of a compilation: 
223 Mood: 
224 Part of set: 
225 Period: 
226 Color: 
227 Parental rating: 
228 Parental rating reason: 
229 Space used: 
230 EXIF version: 
231 Event: 
232 Exposure bias: 
233 Exposure program: 
234 Exposure time: 
235 F-stop: 
236 Flash mode: 
237 Focal length: 
238 35mm focal length: 
239 ISO speed: 
240 Lens maker: 
241 Lens model: 
242 Light source: 
243 Max aperture: 
244 Metering mode: 
245 Orientation: 
246 People: 
247 Program mode: 
248 Saturation: 
249 Subject distance: 
250 White balance: 
251 Priority: 
252 Project: 
253 Channel number: 
254 Episode name: 
255 Closed captioning: 
256 Rerun: 
257 SAP: 
258 Broadcast date: 
259 Program description: 
260 Recording time: 
261 Station call sign: 
262 Station name: 
263 Summary: 
264 Snippets: 
265 Auto summary: 
266 Search ranking: 
267 Sensitivity: 
268 Shared with: 
269 Sharing status: 
270 Product name: 
271 Product version: 
272 Support link: 
273 Source: 
274 Start date: 
275 Billing information: 
276 Complete: 
277 Task owner: 
278 Total file size: 
279 Legal trademarks: 
280 Video compression: 
281 Directors: 
282 Data rate: 
283 Frame height:
284 Frame rate:
285 Frame width: 
286 Total bitrate: 
287 Masters Keywords (debug): 
288 Masters Keywords (debug):
They were listed in a comment here but looks like msdn removed the user comments.

While tooltipinfo.bat can be used for all kind of files imgInfo.bat is for images only.It uses WIA.ImageFile activex object instead of Shell.Application

----------------------------

#9 24 Feb 2018 13:02
Sponge Belly

Hi Pyprohly,

I don’t know anything about PowerShell, sorry. :(

But I can tell you there’s no need to pipe the output of mshta to more when it’s inside the in(…) clause of a for /f loop. In fact, there’s no need for mshta at all! ;)

DosTips user Liviu developed a CMD/WSF Hybrid, which enables programmers to embed unmodified VBScript (and/or JScript) into a Batch file.

I took the liberty of rewriting your code to illustrate the technique:

Code: Select all

<!-- : Batch
@echo off & setLocal enableExtensions disableDelayedExpansion
(call;) %= sets errorLevel to 0 =%

for /f "tokens=1-13 delims=:" %%A in ('
    cScript //noLogo //job:imgProps "%~dpf0?.wsf" "%~1"
') do (
    set "FormatID=%%~A"
    set "FileExtension=%%~B"
    set "Width=%%~C"
    set "Height=%%~D"
    set "HorizontalResolution=%%~E"
    set "VerticalResolution=%%~F"
    set "PixelDepth=%%~G"
    set "IsIndexedPixelFormat=%%~H"
    set "IsAlphaPixelFormat=%%~I"
    set "IsExtendedPixelFormat=%%~J"
    set "IsAnimated=%%~K"
    set "FrameCount=%%~L"
    set "ActiveFrame=%%~M"
) %= for /f =%
echo Dimensions: %Width% x %Height%

endLocal & goto :EOF &:: -->

<job id="imgProps">
<script language="VBScript">
Set o=CreateObject("WIA.ImageFile")

o.LoadFile(WScript.Arguments(0))
WScript.Echo Join(Array(o.FormatID,o.FileExtension,o.Width,o.Height, _
    o.HorizontalResolution,o.VerticalResolution,o.PixelDepth, _
    o.IsIndexedPixelFormat,o.IsAlphaPixelFormat,o.IsExtendedPixelFormat, _
    o.IsAnimated,o.FrameCount,o.ActiveFrame), ":")
</script>
</job>
PS: The WIA.ImageFile object is available on Windows Vista and later.

Last edited by Sponge Belly (25 Feb 2018 12:54)

----------------------------

#10 25 Feb 2018 14:20
Pyprohly

Oh, SB, I wish you had used this technique in your initial demonstration above because it was actually only just two/three days ago since you posted that I looked into finding some sort of a Batch-JScript-VBScript hybrid when I crossed Liviu’s post on this killer Batch-WSF technique, and I’m really digging it. Indeed, it is much superior to any mshta call (speaking of, thanks for the reminder about the redundant pipe to more there).

I had a disfavour for Batch-JScript hybrid solutions because it assumed that whoever you’re demonstrating to hadn’t already consumed that valuable one-WSH-script-call per batch file. Nowadays, I can be more comfortable posting Batch-JScript solutions because if they ask I’ll know how to shuffle the code around, and avoid those script conflicts, and I won’t look dumb… *ahem* …

Moving swiftly away from that awkward moment, this Batch-WSF technique will be useful in this upcoming batch command line argument parser I’m putting together.
Sponge Belly wrote:

I don’t know anything about PowerShell, sorry. sad
Well don’t frown, there’s no reason to stop at 2/3. You should learn it right now, even if just for the handy COM object type introspection (I wonder how you go about exploring COM objects without it? I guess the docs are always available).

@npocmaka The PowerShell script I posted demonstrates how to generate that list (so no need to hang onto that list or link, if for that reason you dug it up for me) but these properties aren’t for ExtendedProperty(), as I’ve mentioned, Dimensions is one of the very few properties that actually work with ExtendedProperty().

The relevant details on ExtendedProperty() can be found here, but it’s use looks fairly involved and it doesn’t seem that it can achieve more than what GetDetailsOf() already can do.

----------------------------

#11 26 Feb 2018 11:38
Sponge Belly

Hi Pyprohly,

Dealing with command line arguments in Batch is notoriously difficult. I recommend reading this Stack Overflow Answer. It’s pretty good, if I say so myself! wink

But only because it’s based on the work of Liviu, Dave Benham, Jeb and others.

Your JScript command line parser sounds interesting. I’ll download it and read through the code. And you’re right: I should learn a little PowerShell. It’s everywhere these days.

Last edited by Sponge Belly (02 Mar 2018 17:48)
Post Reply