Get Image Resolution: Source Code
This movie script will attempt to determine the format and resolution of a graphic file, by directly reading the header.
General notes:
- This is a Movie script. This is NOT a behaviour, NOT a parent script.
- The code will work in Macromedia Director 7.0 or later.
- The code requires the BinaryIO Xtra by Glenn Picher, available at http://www.updatestage.com/xtras/binaryio.html.
Copy and paste the source code below into a movie script.
-- Determine Graphic File Resolution
-- Copyright (c) 2001 Kendall Anderson. All rights reserved.
-- http://invisiblethreads.com
-----------
-- OVERVIEW
-----------
-- Code to read the width/height of a specified graphic file
-- Currently only identifies .BMP, .GIF, .TGA because these formats
-- can be parsed in a very similar way (easily identifiable header,
-- seek to specific location and read data).
-- Note that the .TGA recognition is a little dodgy, so it is tested
-- last, after other formats. (it depends on matching a single number only)
-- Other formats (.JPG, .TIF) require a (little) bit more parsing
-- and could be easily incorporated. This code is meant to serve as
-- an example of the process.
-- Details about file formats found at: http://www.wotsit.org
---------------
-- CODE HISTORY
---------------
-- Nov 17 2001: Kendall Anderson: Initial design and coding
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- given a filename, try to determine the type of graphic file
-- and if successful return the image resolution as a property list
-- [ #width: integer width, #height: integer height ]
on _GetResolution dFilename
--register(xtra "binaryio","your serial num here") -- this should only be done once, elsewhere!
oFile = new(xtra "binaryio")
dErr = openfile(oFile, 1, dFilename)
sType = _DetermineFileType(oFile)
if (sType = 0) then
put "Unidentified file format"
lRes = [ #width: 0, #height: 0 ]
else
lRes = _GetFileResolution(oFile, sType)
put "File type: " & sType
put "Image resolution: w: " & lRes.width & ", h: " & lRes.height
end if
oFile = void
return lRes
end
-- given a file pointer reference, try to determine what kind
-- of file this is by reading the header information
on _DetermineFileType oFile
-- lHeader format:
-- start location of header, # chars to read, text(s) to match
lHeaders = [:]
lHeaders.addProp(#bmp, [ 0, 2, [ "BM", "BA", "CI", "CP", "IC", "PT" ] ])
lHeaders.addProp(#gif, [ 0, 3, [ "GIF" ] ])
lHeaders.addProp(#tga, [ 2, 1, [ numtochar(1), numtochar(2), numtochar(9), numtochar(10) ]])
sType = 0
repeat with i = 1 to lHeaders.count -- check each type until we get a match
bFound = _CheckHeader(oFile, lHeaders[i])
if (bFound) then
sType = lHeaders.getPropAt(i)
exit repeat
end if
end repeat
return sType
end
-- given a file pointer reference and the type of the file,
-- read the image resolution (location of data dependent on file type)
on _GetFileResolution oFile, sType
-- configure location of width value, and length of data for different file types
-- lDetails format:
-- start location of width data, # of bytes for data
-- assumes height data occurs immediately after width, in same format
lDetails = [:]
lDetails.addProp(#bmp, [ 18, #long ])
lDetails.addProp(#gif, [ 6, #short ])
lDetails.addProp(#tga, [ 12, #short ])
return (_ReadResolution(oFile, lDetails[sType]))
end
-- given file pointer, try to read header data to verify file type
on _CheckHeader oFile, lData
bMatch = FALSE
dOffset = lData[1] -- offset where we check for match
dLength = lData[2] -- # of bytes to read
lValid = lData[3] -- list of valid matching strings
-- check id header
setFilePosition(oFile, dOffset)
sID = readBytes(oFile, dLength)
repeat with dItem in lValid -- check for valid matches
if (sID = dItem) then -- if valid match
bMatch = TRUE
exit repeat -- exit loop
end if
end repeat
return bMatch
end
-- given file pointer and data describing location of resolution data,
-- read resolution data and return as proplist
on _ReadResolution oFile, lData
dOffset = lData[1] -- offset where we find data
sType = lData[2] -- data type: #short (2 bytes) or #long (4 bytes)
setFilePosition(oFile, dOffset)
case (sType) of
#short: sMethod = #readUnsignedShort -- handler within BinaryIO
#long: sMethod = #readUnsignedLong -- handler within BinaryIO
end case
dWidth = call(sMethod, oFile)
dHeight = call(sMethod, oFile)
return [ #width: dWidth, #height: dHeight ]
end
