Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 06 Sep 2019, 13:10

GIF Image Size

jeeswg's script to test the IMG_GetImageSize function showed some interesting variances for some image types. I wanted to cover the image size variances found in GIF files.

Much of the appeal of the GIF format is the file size. The small(ish) file size is accomplished by using progressive compression. The first frame is created, the second frame only contains the differences of the first frame, and so on. The first frame sometimes contains the entire image size but often it is missing 1 or two pixel sizes (width and/or height). Sometimes the image size of the first frame can be dramatically different -- 20 to 30 pixel sizes different (width or height) or more. I have several GIF files where the first frame is blank.

The GIF image size is explicitly defined in the first 10 bytes of every GIF file. Without this size information, the decompression routine would not know how to correctly decompress the file. Many of the programs (including the Windows Shell program) appear to get the image size from the first image in the file instead of from the Width and Height fields that are located in the first 10 bytes of the file. I can only imagine that this is done so that the program can get other information or perform other tasks - preview image, identify color depth, etc. One of the programs on my computer (FastStone Image Viewer) does the same thing. In the window that shows a preview of all the image files in the directory, it will show what appears to be the size of the first image of the GIF file. I would wager that it uses the built-in Windows Shell program to get this information. But in the preview window for individual images, it will show the "correct" image size.

TL;DR: The size returned from the IMG_GetImageSize function is correct for GIF files. The size returned from the Windows Shell or other programs that use the size of the first image in the GIF file may not be correct.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 05 Sep 2019, 20:10

tmplinshi wrote:
05 Sep 2019, 17:40
I actually tested the my uploaded file from imgur, same results.
I downloaded the files again with the same it-works-correctly-for-me results. Weird stuff. Let me just put it out there. Is anyone getting the same results as tmplinshi? Thanks.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by tmplinshi » 05 Sep 2019, 17:40

I actually tested the my uploaded file from imgur, same results.

My Windows 10 do have some weird problems, I cannot turn on the UAC..

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 05 Sep 2019, 15:28

SomeGuest wrote:
05 Sep 2019, 07:02
https developers.google.com /speed/webp/gallery1 Broken Link for safety
https developers.google.com /speed/webp/gallery2 Broken Link for safety
Thanks SomeGuest. This is the site that I download the few images that I have to to test the WebP format. If you (or anyone) find any others, please let me know.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 05 Sep 2019, 15:20

tmplinshi wrote:
05 Sep 2019, 13:08
Testing for GetImageSize Test - Release 6.ahk
  • PNG files are not working, all returned 0x0 size. Sample.png
  • The size of Sample.jpg is 1001x1334, but the script get 1334x1001.
Tested on Windows 10 64-bit, AHK v1.1.30.03 U32/U64.
I tested both of these file on my computer (Windows 7) and the function returned the correct value for both images. Obviously, you need to uninstall Windows 10 immediately! :)

Unless it really is a Windows 10 problem (it's not), it's possible that idiosyncrasies in the file were corrected when the images were uploaded to imgur or when I downloaded them from imgur. If possible, could you load the original problem files to a zip file and PM them to me? It would be helpful to see the files in their original condition.

Thank you for your assistance.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by tmplinshi » 05 Sep 2019, 13:08

Testing for GetImageSize Test - Release 6.ahk
  • PNG files are not working, all returned 0x0 size. Sample.png
  • The size of Sample.jpg is 1001x1334, but the script get 1334x1001.
Tested on Windows 10 64-bit, AHK v1.1.30.03 U32/U64.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by SomeGuest » 05 Sep 2019, 07:02

https developers.google.com /speed/webp/gallery1 Broken Link for safety
https developers.google.com /speed/webp/gallery2 Broken Link for safety

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 05 Sep 2019, 04:27

Code: Select all

vListExt := " ;continuation section
(
ani
	bmp
cur
emf
	gif
ico
	jpg (jpeg, jpe, jif, jfif, jfi)
pcx
	png
	svg
tif
	wdp (hdp, jxr)
	webp
wmf
)"
This pretty much covers all the extensions that I've tested with the following exceptions.

hdp, jxr - I've never found any files with this extension on my computer or in the wild. The files should have the same format as wdp but I can't be sure. If you have any files that were explicitly created with these extensions, be sure to examine the results carefully.

webp - I have a very limited number of files with this extension. If you have any of these files, be sure to examine the results carefully.

Exif - This format is supposed to have the same header as JPEG but I don't have a digital camera or any device that explicitly exports using this format. Most pictures taken from a phone or similar have Exif tags but I don't think that is same thing. If you have any files with this format, be sure to test them as well. According to Wikipedia, Exif files could have a .JPG, .TIF, or .WAV file extension.

Thank you for your assistance. It is appreciated.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jeeswg » 04 Sep 2019, 19:39

I wrote some code to test the IMG_GetImageSize function.
Note: I had to determine which extensions to check. Do suggest any extensions that I missed.

Code: Select all

;[IMG_GetImageSize function]
;Expert Challenge: Get width and height from an image file reading as few bytes as possible. - Page 2 - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=17&t=66880

;get image dimensions via GetDetailsOf and via IMG_GetImageSize

#NoEnv
SetBatchLines, -1
ListLines, Off

;vDir1 := "C:\Users\" A_UserName "\Pictures"
vDir1 := "C:"

vOutput := ""
VarSetCapacity(vOutput, 1000000*2)

;note: tabbed: extensions I see in image search results
vListExt := " ;continuation section
(
ani
	bmp
cur
emf
	gif
ico
	jpg (jpeg, jpe, jif, jfif, jfi)
pcx
	png
	svg
tif
	wdp (hdp, jxr)
	webp
wmf
)"
vListExt := RegExReplace(vListExt, "\W+", ",")
MsgBox, % vListExt

vCount := 0
Loop Files, % vDir1 "\*", % "FR"
{
	vPath := A_LoopFileFullPath
	SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
	if vExt not in % vListExt
		continue
	IMG_GetImageSize(vPath, vImgW1, vImgH1)
	vImgW2 := RegExReplace(JEE_FileGetDetail(vPath, "Width"), "\D")
	vImgH2 := RegExReplace(JEE_FileGetDetail(vPath, "Height"), "\D")
	;if !(vImgW1 " " vImgH1 = vImgW2 " " vImgH2)
	;	MsgBox, % vPath "`r`n" vImgW1 " " vImgH1 "`r`n" vImgW2 " " vImgH2
	if !(vImgW1 " " vImgH1 = vImgW2 " " vImgH2)
		vOutput .= vPath "`t" vImgW1 " " vImgH1 "`t" vImgW2 " " vImgH2 "`r`n"
		, vCount++
}
vPath := A_Desktop "\z img sizes " A_Now ".txt"
FileAppend, % vOutput, % "*" vPath, UTF-8
MsgBox, % "done"
return

;==================================================

;JEE_FileGetProperty
;JEE_FileGetProperties
;this term (e.g. 'Length') may vary depending on the locale
JEE_FileGetDetail(vPath, vDetail)
{
	local
	static oMap := IsFunc("Map") ? Func("Map").Call() : {}
	if !FileExist(vPath)
		return
	SplitPath, vPath, vName, vDir
	oShell := ComObjCreate("Shell.Application")
	oFolder := oShell.NameSpace(vDir "\")
	oFilename := oFolder.Parsename(vName)
	if oMap.HasKey("z" vDetail)
	{
		vValue := oFolder.GetDetailsOf(oFilename, oMap["z" vDetail])
		oShell := oFolder := oFilename := ""
		return vValue
	}
	Loop
	{
		vDetail2 := oFolder.GetDetailsOf(oFolder.Items, A_Index-1)
		if (vDetail2 = "")
			break
		if (vDetail = vDetail2)
		{
			vValue := oFolder.GetDetailsOf(oFilename, A_Index-1)
			oMap["z" vDetail] := A_Index-1
			break
		}
	}
	oShell := oFolder := oFilename := ""
	return vValue
}

;==================================================

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 02 Sep 2019, 14:34

OK, one more time.

Added support for icons (ICO) and standard cursors (CUR). See the function documentation for the methodology. It won't make everybody happy and it's not as fast as the other image formats but the results appear to be consistent. It also appears to be the same size returned by the AutoHotkey LoadPicture function when a size is not specified and when the icon or cursor is loaded from a stand-alone icon or cursor file. This is not true if loading an icon from a module (Ex: "shell.dll") but that's a problem for another function.

Added preliminary support for Scalable Vector Graphics (SVG). It was written using simple string matching tests. If the file is formatted correctly, it should work. However, I don't have enough test files to call this a done deal.

Added support for image handles. If a bitmap, cursor, or icon handle is passed to the function instead of a file path, the function will return the size of the image.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

With the exception of bug fixes, this is the final release of this mini-project in this forum. Additional releases (if any) will be posted in the Scripts forum.

Thanks to everyone who has taken the time and effort to download and test this function. It is appreciated. Please make a noise if you find a problem with any image format.
Attachments
GetImageSize Test - Release 6.ahk
(42.35 KiB) Downloaded 209 times

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 23 Aug 2019, 03:09

OK. Added support for Animated Cursor (ANI), JPEG extended range (JPEG XR), and PiCture eXchange (PCX). I have very few test files for JPEG XR (.hdp, .jxr, and .wdp file extensions) so testing of this format would be appreciated.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm working on icons and standard cursors. The code is pretty much ready-to-go but I'm not entirely satisfied with the logic for determining which size is returned when there are multiple image sizes.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.
Attachments
GetImageSize Test - Release 5.ahk
(29.74 KiB) Downloaded 136 times

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jeeswg » 22 Aug 2019, 18:58

Thanks for adding webp support. Much appreciated.

Re. icons. The easiest to get should be default. But max (and perhaps min) seem like good options.

Re. jxr:
- The jxr/wdp (JPEG XR) format seems to be the standard for (amongst others): telegraph.co.uk and washingtonpost.com (at least on Internet Explorer).
- Of downloaded images, I'm seeing these by frequency (and no other file types):
- jpg/png/(jpeg=jpg)/gif/svg/jxr/webp/bmp/(wdp=jxr).
- Hopefully, since it's a JPEG format, the jxr logic should be similar to some of your existing jpeg logic.

Links (various):
show svg/wdp/jxr/animated gif image files in a GUI - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=28658
Internet Explorer controls: scrollbars, borders, navigation sounds, image dimensions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=50189

Links (jxr/wdp):
telegraph.co.uk
washingtonpost.com

Links (webp):
WebP - Wikipedia
https://en.wikipedia.org/wiki/WebP
File:Vulphere WebP OTAGROOVE demonstration 2.webp - Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Vulphere_WebP_OTAGROOVE_demonstration_2.webp
Gui support for webp image format - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=66335

Links (animated gifs) (a query by me):
animated gifs: binary data - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=67338

Links (icons) (a query by skrommel, in case you can help, thanks):
[Function] Resize and Convert Images - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=2505&p=169302#p169302

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 20 Aug 2019, 01:25

Icons and Cursors and Animated Cursors, Oh My!

Just to keep you up to date, I've been working on adding icons and cursors but I knew from the get-go that there would be issues because these file types can hold multiple images with multiple sizes. How can a "GetImageSize" function return a single image size if the file contains images with more than one size?

In the order of complexity or the number of problems...

Animated Cursors
Animated cursor files (Ex: "MyAnimatedCursor.ani") can theoretically include multiple image sizes but they usually (always?) only have one size so it's safe (or at least it's consistent) to return the size of the first image in the file.

Standard Cursors
Standard cursor files (Ex: "MyCursor.cur") can and do include multiple image sizes.

Microsoft system functions that load cursors are not consistent when requested to load a cursor and specific size is not specified. The LoadImage system function will get the first cursor in the file whereas the LoadCursorFromFile system function will get the 32x32 cursor if it exist, otherwise it will get the first image in the file. ##### Check that. This may not be true. The function may return a 32x32 image regardless of what size cursors that are in the file. I need to test it to be sure.

The AutoHotkey LoadPicture command appears to use the LoadImage (or similar) system function for stand-alone cursor files. The first cursor in the file is loaded if no size is specified.

There is no "correct" answer but the "best" and certainly fastest answer might be to return the size of the first cursor in the file. The results would match the LoadImage system function and the AutoHotkey LoadPicture command when no size is specified.

Icons
Please excuse the rambling style of this topic. Too many considerations and too little time to format it into a concise thesis.

Icon files (Ex: "MyIcon.ico") can and do include multiple image sizes. Asking for the icon's image size can be a fool's errand.

With a file that has multiple icon sizes, is there one icon size that should be returned when calling a "GetIconSize" function? The answer has to be Yes because you would except to get a size if the file had only one icon. Wouldn't you expect something if the file has multiple icons? Well then, what size should should be returned then? The best or most logical answer is probably the size of the default icon.

So... What the heck is the default icon, and how does one determine which icon in a group of icons is the default? First of all, there is no such thing as a "default" icon. Well, not officially. However, "default" is an appropriate term to describe the icon that is returned when a size is not specified. In other words, when the specified Width and Height values are zero (0). The system functions designed to load an icon from a stand-alone file (primarily LoadImage) all return the same icon when no size is specified so they provide a good template for determining the default icon. The bad news is the selection criteria includes factors that can change depending on the current video mode. The first icon that works best with the current video mode becomes the default icon.

There are other basic considerations. The image size is stored in 1-byte fields. This allows for an image size from 0 to 255. In the past (before Vista?), 0 always indicated an image size of 256 but now, 0 means any size over 255. Assuming 256 is a fairly safe bet but it not a sure thing. The only way to know for sure is to get the image size directly from the bitmap or PNG image. This is not a quick or inexpensive task for a script.

OK, I'm getting lost. Let me try to regroup.

The function could (and should) include code to deal with all of these issues but I'm thinking that I don't want to write it. Even if I did write it, the entire icon file would need to read in many cases so it wouldn't be any faster than calling a system function to load the icon.

The best and most efficient solution might be a southern engineered solution. If the file contains a single icon and the icon size is between 1 and 255, return that size. Otherwise, call a system function (probably LoadImage) to load the default (or only) icon and return the size of that icon. There is extra code needed to get the size of loaded icon but it's not too bad. This solution certainly won't be as fast as the other image formats but it may be the way to go.

Final Thoughts
Them be my thoughts. I would appreciate your thoughts on these issues.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 17 Aug 2019, 10:26

Thanks for the links SomeGuest. :salute: I will take a look/see.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by SomeGuest » 16 Aug 2019, 15:20

11 emf files https git . uni-paderborn . de /julian93/veins/tree/44253e6bdfe3e558a1c37f9d8a9b604877385bac/doc/interfaces/PhyLayer/tex/images/emf/modelling Broken Link for safety

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by SomeGuest » 16 Aug 2019, 15:13

You can download 70 wmf files here (if you just download the repo, 30mb, it will have a clipart folder with wmf files) - they all seem to work correctly:

resources . oreilly . com/examples/9780735615175/tree/ec379dccb82814da30154357d7bc0311fdd8538a/9780735615175_files/Clip%20Art

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 16 Aug 2019, 14:39

OK. The bugs in the TIFF format have been fixed. The changes primarily fix bugs in the code for the big endian TIFF format but the integrity for both TIFF formats has been improved/fixed.

Thanks to SomeGuest for providing a link to a bunch of TIFF files. Not only did these files help to identify the bugs in the code, they helped to identify that not all programs can read TIFF file correctly, especially the older TIFF files. AutoHotkey (using GDI+) could not read more than a dozen of the files. My image viewer could read most but not all.

As before, I've attached a near-ready-to-run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I'm still looking for EMF and WMF files for testing. If you have or find any, please make a noise.

Feedback would be appreciated, especially if find a problem. Thank you for your assistance.
Attachments
GetImageSize Test - Release 4.ahk
(24.71 KiB) Downloaded 172 times

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 16 Aug 2019, 11:02

Thanks for the TIFF files SomeGuest. :thumbup: They are very useful. I will publish an update that will include corrections for TIFF files shortly.

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by SomeGuest » 16 Aug 2019, 08:44

Some old(er) MM tiffs here www . simplesystems . org / libtiff/images.html - about 50% work, 50% incorrect

Re: Expert Challenge: Get width and height from an image file reading as few bytes as possible.

Post by jballi » 15 Aug 2019, 09:39

OK. The accuracy problem for EMF has been fixed. However, the calculation was adjusted to match GDI+. See the function documentation for more information.

As before, I've attached a near-ready-to run script that includes the necessary functions. You will need to make a minor change to point to image files on your computer.

I have very few EMF and WMF files for testing. Some of the EMF files were generated from other file types just to create more EMF files to test. I fear that my test results for EMF and WMF data is skewed and doesn't really represent what really out there. If you have any EMF and/or WMF files, please include those files in your tests.

I'm also still looking for big endian TIFF files. These would be old TIFF files created on Motorola or IBM chips. Stuff created on an old Mac for example. The files will have "MM" in the first two bytes of the file.

Feedback would be appreciated, especially if you find a problem. Thank you for your assistance.
Attachments
GetImageSize Test - Release 3.ahk
(22.95 KiB) Downloaded 195 times

Top