Page 2 of 4
Re: Get image width and height without loading image
Posted: Tue Mar 17, 2015 10:04 am
by Michael Vogel
Hm,
had some time to investigate wilberts code - like the method using the memory array!
Maybe I can include the other formats (jpeg2, bmp etc.) into wilberts scheme next weekend.
Just two small things...
*) the check for fileextensions could be problematic for extensions different to 3 characters ("something.nojpeg")
*) FFCC seems to be excluded as well for JPEGs, so what about changing the code to...
Code: Select all
:
:
If *MemArray\w[0] & $F0FF= $C0FF
a = *MemArray\a[1]
If a=$C0 Or a&3
*Size\Width = *MemArray\a[5] << 8 | *MemArray\a[6]
*Size\Height = *MemArray\a[3] << 8 | *MemArray\a[4]
:
:
Re: Get image width and height without loading image
Posted: Tue Mar 17, 2015 10:20 am
by wilbert
Michael Vogel wrote:*) the check for fileextensions could be problematic for extensions different to 3 characters ("something.nojpeg")
I am aware of that but all normal file extensions for images I know of are 3 or 4 characters.
It will accept your .nojpeg example as well but since it's only a pre-check, such a file will be recognized as not being an image later on when you check the first four bytes of the file.
When I compared my procedure with the FindString/LCase/GetExtensionPart construction you were using it was about 10 times faster so even with a few false positives it will probably still be a faster approach.
Re: Get image width and height without loading image
Posted: Fri Mar 20, 2015 2:48 pm
by Michael Vogel
Converted the source code into "Wilbert-style" - supports BMP, GIF, JPEG, JPEG2000, PCX, PNG, TGA, TIF images.
Code: Select all
Structure ImageSizeType
Width.l
Height.l
EndStructure
Procedure.l CheckImageName(*Name)
!xor eax, eax
!xor ecx, ecx
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rdx, [p.p_Name]
!iiname_loop:
!shrd eax, ecx, 8
CompilerIf #PB_Compiler_Unicode
!mov cx, [rdx]
!add rdx, 2
CompilerElse
!movzx cx, byte [rdx]
!inc rdx
CompilerEndIf
CompilerElse
!mov edx, [p.p_Name]
!iiname_loop:
!shrd eax, ecx, 8
CompilerIf #PB_Compiler_Unicode
!mov cx, [edx]
!add edx, 2
CompilerElse
!movzx cx, byte [edx]
!inc edx
CompilerEndIf
CompilerEndIf
!test cx, cx
!jnz iiname_loop
!or eax, 0x20202020
!cmp eax, '.bmp'
!je iiname_exit
!cmp eax, '.gif'
!je iiname_exit
!cmp eax, '.jp2'
!je iiname_exit
!cmp eax, '.jpg'
!je iiname_exit
!cmp eax, '.pcx'
!je iiname_exit
!cmp eax, '.png'
!je iiname_exit
!cmp eax, 'jpeg'
!je iiname_exit
!cmp eax, '.tif'
!je iiname_exit
!cmp eax, '.tga'
!je iiname_exit
!xor eax, eax
!iiname_exit:
ProcedureReturn
EndProcedure
Procedure ImageFileDimension(filename.s,*imagesize.ImageSizeType)
#ImageMinimumSize= 24
#ImageHeaderSize= 2048
#ImageHeaderGIF= $38464947; 'GIF8'
#ImageHeaderJPG= $E0FFD8FF; -
#ImageHeaderJP2= $0C000000; -
#ImageHeaderPNG= $474E5089; '‰PNG'
#ImageHeaderBMP= $4D42; 'BM'
#ImageHeaderTIF_LSB= $4949; 'II'
#ImageHeaderTIF_MSB= $4D4D; 'MM'
#ImageHeaderPCX= $0A; -
#ImageHeaderTGA= $01; -
Structure MemArray
StructureUnion
a.a[0]
w.w[0]
l.l[0]
EndStructureUnion
EndStructure
Protected *Buffer.MemArray
Protected *MemArray.MemArray
Protected BytesRead.i
Protected a.a,n.l,m
#ImageFile=666
*imagesize\width=#Null
*imagesize\height=#Null
If CheckImageName(@FileName)
If ReadFile(#ImageFile,FileName, #PB_File_NoBuffering)
*Buffer=AllocateMemory(#ImageHeaderSize,#PB_Memory_NoClear)
BytesRead=ReadData(#ImageFile,*Buffer,#ImageHeaderSize)
If BytesRead>=#ImageMinimumSize
Select *Buffer\l[0]&$FFFFFFFF
Case #ImageHeaderJPG
n=*Buffer\a[4]<< 8|*Buffer\a[5]+4
If n>20
FileSeek(0,n)
BytesRead=ReadData(#ImageFile,*Buffer,#ImageHeaderSize)
n=0
EndIf
*MemArray=*Buffer+n
While *MemArray-*Buffer+6<BytesRead
If *MemArray\a[0]=$FF
a=*MemArray\a[1]
If a=$c0 Or (a>>4=$C And a&3)
*imagesize\width=*MemArray\a[7]<<8|*MemArray\a[8]
*imagesize\height=*MemArray\a[5]<<8|*MemArray\a[6]
Break
EndIf
Else
Break
EndIf
*MemArray+*MemArray\a[2]<<8|*MemArray\a[3]+2
Wend
Case #ImageHeaderPNG
*imagesize\width=*Buffer\a[18]<<8|*Buffer\a[19]
*imagesize\height=*Buffer\a[22]<<8|*Buffer\a[23]
Case #ImageHeaderGIF
*imagesize\width=*Buffer\w[3]
*imagesize\height=*Buffer\w[4]
Case #ImageHeaderJP2
n=*Buffer\a[14]<<8|*Buffer\a[15]+35
If n<#ImageHeaderSize
*imagesize\width=*Buffer\a[n-1]<<8|*Buffer\a[n]
*imagesize\height=*Buffer\a[n-5]<<8|*Buffer\a[n-4]
EndIf
Default
Select *Buffer\w[0]&$FFFF
Case #ImageHeaderBMP
*imagesize\width=*Buffer\w[9]
n=*Buffer\w[11]&$FFFF
If n<0
n=-n
EndIf
*imagesize\height=n
Case #ImageHeaderTIF_LSB
a=0
n=*Buffer\l[1]
If n<#ImageHeaderSize
n>>1
m=*Buffer\w[n]
n+1
While m
Select *Buffer\w[n]
Case $100
*imagesize\width=*Buffer\w[n+4]
a|1
Case $101
*imagesize\height=*Buffer\w[n+4]
a|2
EndSelect
If a=3
m=0
Else
n+6
m-1
EndIf
Wend
EndIf
Case #ImageHeaderTIF_MSB
a=0
n=*Buffer\a[6]<<8|*Buffer\a[7]
If n<#ImageHeaderSize
m=*Buffer\a[n]<<8|*Buffer\a[n+1]
n+2
While m
Select *Buffer\a[n]<<8|*Buffer\a[n+1]
Case $100
*imagesize\width=*Buffer\a[n+8]<<8|*Buffer\a[n+9]
a|1
Case $101
*imagesize\height=*Buffer\a[n+8]<<8|*Buffer\a[n+9]
a|2
EndSelect
If a=3
m=0
Else
n+12
m-1
EndIf
Wend
EndIf
Default
Select *Buffer\a[0]
Case #ImageHeaderPCX
If *Buffer\a[1]<6
*imagesize\width=*Buffer\w[4]+1
*imagesize\height=*Buffer\w[5]+1
EndIf
Case #ImageHeaderTGA
If *Buffer\a[1]<2 And *Buffer\a[2]&%11110100=0
*imagesize\width=*Buffer\w[6]
*imagesize\height=*Buffer\w[7]
EndIf
EndSelect
EndSelect
EndSelect
EndIf
FreeMemory(*Buffer)
CloseFile(#ImageFile)
EndIf
EndIf
Debug "------ "+GetFilePart(filename)+" ------"
Debug Str(*imagesize\Width)+" x "+Str(*imagesize\Height)
EndProcedure
x.ImageSizeType
ImageFileDimension("Data\PB.gif",x)
ImageFileDimension("Data\LSB.tif",x)
ImageFileDimension("Data\MSB.tif",x)
ImageFileDimension("Data\Willi.jpg",x)
ImageFileDimension("Data\Logo.jp2",x)
ImageFileDimension("Data\Bird.png",x)
ImageFileDimension("Data\Logo.bmp",x)
ImageFileDimension("Data\Bert.bmp",x)
ImageFileDimension("Data\Logo.pcx",x)
ImageFileDimension("Data\Logo.tga",x)
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 9:17 am
by Fangbeast
Using the code above, I just added the below code to get the dimensions of images. 2 jpeg files failed although WIndows can see them and I can load them manually.
How do I get the bit depth as well?
Code: Select all
DirectoryEntryId.i = ExamineDirectory(#PB_Any, "Pictures\", "*.*")
If DirectoryEntryId.i
Repeat
TypeOfFile = NextDirectoryEntry(DirectoryEntryId.i)
FileName.s = DirectoryEntryName(DirectoryEntryId.i)
If TypeOfFile = 1
If FileName.s <> "." And FileName.s <> ".."
ImageFileDimension("Pictures\" + FileName.s, x)
EndIf
EndIf
Until TypeOfFile = 0
EndIf
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 9:40 am
by wilbert
Fangbeast wrote:Using the code above, I just added the below code to get the dimensions of images. 2 jpeg files failed although WIndows can see them and I can load them manually.
You can try if there's a difference between the implementation I did (
http://www.purebasic.fr/english/viewtop ... 70#p462670 ) and the one Michael did (
http://www.purebasic.fr/english/viewtop ... 53#p462853 ).
If it doesn't make a difference, you can try to increase the #ImageHeaderSize value from 2048 to 3072 or 4096.
If it still isn't working, I don't know. You could share the jpg to take a look at it.
Fangbeast wrote:How do I get the bit depth as well?
That would be different for each image type.
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 11:31 am
by Fangbeast
I would change things if I knew what I was doing but this is assembly/assembler so I am out of luck.
Not to worry, I will try something else for now, thanks for the help.
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 2:31 pm
by JHPJHP
See my
Services, Stuff, and Shellhook post for an alternate solution.
- Stuff/GadgetStuff/WebGadget/ImageSize.pb
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 3:14 pm
by Kiffi
here is a COMate-Solution:
Code: Select all
EnableExplicit
IncludePath "YourPathTo\COMatePLUS\"
XIncludeFile "COMatePLUS.pbi"
Procedure.s GetVbsCode(Filename.s)
Protected VbsCode.s
VbsCode = "CONST cWIDTH = 162" + #CRLF$ +
"CONST cHEIGHT = 164" + #CRLF$ +
"Set oShell = CreateObject(" + Chr(34) + "Shell.Application" + Chr(34) + ")" + #CRLF$ +
"Set oFolder = oShell.Namespace(#FOLDER#)" + #CRLF$ +
"Set oFile = oFolder.ParseName(#FILE#)" + #CRLF$ +
"width = oFolder.GetDetailsOf(oFile, cWIDTH)" + #CRLF$ +
"height = oFolder.GetDetailsOf(oFile, cHEIGHT)" + #CRLF$
VbsCode = ReplaceString(VbsCode, "#FOLDER#", Chr(34) + GetPathPart(Filename) + Chr(34))
VbsCode = ReplaceString(VbsCode, "#FILE#", Chr(34) + GetFilePart(Filename) + Chr(34))
ProcedureReturn VbsCode
EndProcedure
Define.COMateObject scriptObject, errorObject
Define Filename.s
Define width.s, height.s
Filename = "YourImage"
scriptObject = COMate_CreateObject("MSScriptControl.ScriptControl.1")
If scriptObject
scriptObject\SetProperty("Language = 'VBScript'")
If scriptObject\Invoke("AddCode('" + GetVbsCode(Filename) + "')") = #S_OK
width.s = scriptObject\GetStringProperty("Eval('width')")
height.s = scriptObject\GetStringProperty("Eval('height')")
MessageRequester(GetFilePart(Filename), "Width: " + width + #CRLF$ + "Height: " + height)
Else
errorObject = scriptObject\GetObjectProperty("Error")
If errorObject
MessageRequester("Script demo - error reported!", Chr(34) + errorObject\GetStringProperty("Text") + Chr(34) + #LF$ + " produced the following error : " + #LF$ + #LF$ + errorObject\GetStringProperty("Description"))
errorObject\Release()
EndIf
EndIf
scriptObject\Release()
Else
MessageRequester("COMate - Scripting demo", "Couldn't create the scripting object!")
EndIf
Greetings ... Peter
Re: Get image width and height without loading image
Posted: Tue Sep 29, 2015 7:39 pm
by Michael Vogel
Fangbeast wrote:Using the code above, I just added the below code to get the dimensions of images. 2 jpeg files failed although WIndows can see them and I can load them manually.
Maybe you can upload them somewhere - this would allow to do check what's going on...
Re: Get image width and height without loading image
Posted: Fri Oct 02, 2015 7:19 am
by Fangbeast
Michael Vogel wrote:Fangbeast wrote:Using the code above, I just added the below code to get the dimensions of images. 2 jpeg files failed although WIndows can see them and I can load them manually.
Maybe you can upload them somewhere - this would allow to do check what's going on...
Thanks Michael but I went back to the pb way of doing it originally. Limited time in october, blood tests, hospital visits, birthdays etc. The little picture database now works fine.
Just need to decide whether to allow a default category during mass import and then I am finished.
Re: Get image width and height without loading image
Posted: Fri Oct 02, 2015 11:51 am
by RASHAD
Hi Fangles
- Download ImageMagick (It is freeware)
- Use the command line identify.exe "Your image file name" through PB command Runprogram()
- You will get what you want in no time
Re: Get image width and height without loading image
Posted: Fri Oct 02, 2015 2:16 pm
by Fangbeast
RASHAD wrote:Hi Fangles
- Download ImageMagick (It is freeware)
- Use the command line identify.exe "Your image file name" through PB command Runprogram()
- You will get what you want in no time
Thanks RASHAD but as I said to Michael above "Thanks Michael but I went back to the pb way of doing it originally. Limited time in october, blood tests, hospital visits, birthdays etc. The little picture database now works fine.
Re: Get image width and height without loading image
Posted: Fri Oct 02, 2015 2:38 pm
by RASHAD
I wish you the best with October Fang
BTW identify.exe will cover a lot of formats much more than what PB cover
Beside it can analyze more than one image file in one run
Do test it after October
My best wishes for you my friend
Re: Get image width and height without loading image
Posted: Sun Oct 04, 2015 10:42 am
by Michael Vogel
Fangbeast, all the best for you - hopefully you will have better times soon...
...then, if you like, we'll continue with this thread here

Re: Get image width and height without loading image
Posted: Sun Oct 04, 2015 11:21 am
by Vera
Wishing you good results Fangbeast and happy celebrations
