def parseJp2Profile(jp2Profile): # Read profile contents to bytes object profileBytes=shared.readFileBytes(jp2Profile) # Parse XML tree try: root = ET.fromstring(profileBytes) except Exception: msg="error parsing " + jp2Profile shared.errorExit(msg) options=root.find("./aware") # Initialise 2 lists to store results # Earlier version used dictionary, but some Aware options may have more # than one occurrence, so that doesn't work! # TODO: Why not use element instead? optionNames=[] optionValues=[] for node in options.iter(): # Iter returns child elements as well as element itself! if node.tag!="aware": optionNames.append(node.tag) optionValues.append(node.text) return(optionNames,optionValues)
def main(): # Get input from command line args=parseCommandLine() imageIn=args.imageIn imageOut=args.imageOut jp2Profile=args.profile suffixOut=args.suffix flagMetadata=args.flagMetadata flagLogging=args.flagLogging # Input image(s) as file list imagesIn=glob.glob(imageIn) if not imagesIn: # If imageIn refers to non-existing files, imagesIn is empty # jpwrappa will exit with an error if this happens msg=imageIn + " does not exist!" shared.errorExit(msg) # Normalise output images(s) path (may be a directory!) imageOut=os.path.normpath(args.imageOut) # Normalise profile path (if a profile is provided) if jp2Profile != "": jp2Profile=os.path.normpath(jp2Profile) # Perform conversion imagesOut,log=imagesToJP2(imagesIn,imageOut,jp2Profile,suffixOut,flagMetadata) if flagLogging==True: # Write xml-formatted log to stdout print(log.toxml().decode('ascii'))
def getConfiguration(): # What platform are we on? platform = os.name # From where is this script executed?) applicationPath=os.path.abspath(get_main_dir()) # If we're working under Linux and using a frozen (Debian-packaged) version, # root path of config file and default profiles dir is under /etc if platform == "posix" and main_is_frozen(): rootPath = "/etc/jpwrappa" else: rootPath = applicationPath # Configuration file configFile=shared.addPath(rootPath,"config.xml") # Check if config file exists and exit if not shared.checkFileExists(configFile) # Read contents to bytes object configBytes=shared.readFileBytes(configFile) # Parse XML tree try: root=ET.fromstring(configBytes) except Exception: msg="error parsing " + configFile shared.errorExit(msg) # Create empty element object & add config contents to it # A bit silly but allows use of findElementText in etpatch config=ET.Element("bogus") config.append(root) j2kDriverApp=config.findElementText("./config/j2kDriverApp") exifToolApp=config.findElementText("./config/exifToolApp") # Default JP2 profile jp2ProfileDefault=os.path.normpath(rootPath + "/profiles/default.xml") # Normalise all paths j2kDriverApp=os.path.normpath(j2kDriverApp) exifToolApp=os.path.normpath(exifToolApp) # Check if j2kDriverApp and jp2ProfileDefault exist, and exit if not shared.checkFileExists(j2kDriverApp) shared.checkFileExists(jp2ProfileDefault) return(j2kDriverApp,exifToolApp,jp2ProfileDefault)
def getConfiguration(): # From where is this script executed?) applicationPath=os.path.abspath(get_main_dir()) # Configuration file configFile=shared.addPath(applicationPath,"config.xml") # Check if config file exists and exit if not shared.checkFileExists(configFile) # Read contents to bytes object configBytes=shared.readFileBytes(configFile) # Parse XML tree try: root=ET.fromstring(configBytes) except Exception: msg="error parsing " + configFile shared.errorExit(msg) # Create empty element object & add config contents to it # A bit silly but allows use of findElementText in etpatch config=ET.Element("bogus") config.append(root) j2kDriverApp=config.findElementText("./config/j2kDriverApp") exifToolApp=config.findElementText("./config/exifToolApp") # Default JP2 profile jp2ProfileDefault=os.path.normpath(applicationPath + "/profiles/default.xml") # Normalise all paths j2kDriverApp=os.path.normpath(j2kDriverApp) exifToolApp=os.path.normpath(exifToolApp) # Check if j2kDriverApp and jp2ProfileDefault exist, and exit if not shared.checkFileExists(j2kDriverApp) shared.checkFileExists(jp2ProfileDefault) return(j2kDriverApp,exifToolApp,jp2ProfileDefault)
def imagesToJP2(imagesIn,fileOut,jp2Profile,suffixOut,flagMetadata): # Convert one or more images to JP2. Arguments: # # - imagesIn: list of input image(s) # - fileOut: name of output JP2 image or directory for writing output images # - jp2ProfileName: name of JP2 options profile (e.g. KB_lossless / KB_lossy) # - suffixOut: suffix that is added to names of output images (this does NOT # include the file extension, and by default it is an empty text string) # - flagMetaData: True if metadata extraction is needed, False otherwise # # Returns all output images as list # Get configuration settings (yields paths to j2kDriverApp and exifToolApp, # log file and default JP2profile) j2kDriverApp,exifToolApp,profileDefault=getConfiguration() if flagMetadata==True: shared.checkFileExists(exifToolApp) # Create element object that will hold log info log=ET.Element('jpwrappa') # Use default JP2 profile if profile is not specified if jp2Profile=="": jp2Profile=profileDefault # Does JP2 profile exist? shared.checkFileExists(jp2Profile) # Parse JP2 profile optionNames, optionValues=parseJp2Profile(jp2Profile) # Options to text string aOptionsAsString=optionsToString(optionNames,optionValues) # Number of input images numberOfImages=len(imagesIn) # Does fileOut point to a directory? fileOutIsDir=os.path.isdir(fileOut) # If we have multiple input images fileOut should be a directory if numberOfImages > 1 and fileOutIsDir==False: msg=fileOut + " : expected directory" shared.errorExit(msg) # Create list for storing names of output images imagesOut=[] # Create list of output image names if fileOutIsDir==False: imagesOut.append(fileOut) else: for i in range(numberOfImages): imageIn=imagesIn[i] imageOut=shared.constructFileName(imageIn,fileOut,"jp2", suffixOut) imagesOut.append(imageOut) # Convert all images for i in range(numberOfImages): imageIn=imagesIn[i] imageOut=imagesOut[i] # Convert image conversionInfo=convertOneImageToJP2(imageIn,imageOut,aOptionsAsString,exifToolApp, j2kDriverApp,flagMetadata) # Add reference to profile to conversionInfo conversionInfo.appendChildTagWithText("profile", jp2Profile) # Add as child to log element log.append(conversionInfo) return(imagesOut,log)