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)
def convertOneImageToJP2(imageIn,imageOut,awareOptionsString,exifToolApp,j2kDriverApp,extractMetadataFlag): # Convert one image to JP2. Arguments: # # imageIn: name of input image # imageOut: name of output JP2 image # awareOptionsString: text string with Aware options # exifToolApp: path to ExifTool executable # j2kDriverApp: path to Aware executable # extractMetadataFlag: True if metadata extraction is needed, False otherwise # Initialise exit status flag + output strings for ExifTool /Aware # (in case extractMetadataFlag equals 0) exifExitStatus=0 awareExitStatus=0 exifStdOut="" exifStdErr="" awareStdOut="" awareStdErr="" # Does input image exist? imageInExists=os.path.isfile(imageIn) #if imageInExists==False: # If output image already exists, delete it! Why this? --> # 1. If the conversion proceeds as planned, it will be overwritten anyway, BUT ... # 2. If something goes wrong and the image cannot be created, the absence of # the output image may be the only way to find out about this afterwards # (because we cannot rely on Aware's exit status for this, see below) shared.removeFile(imageOut) # Absolute path to output image (location also used for temporary file) pathOut=os.path.abspath(os.path.split(imageOut)[0]) # Metadata extraction (optional) # Initialise Aware command line option for metadata embedding aMetadata="" if extractMetadataFlag==True: # Generate name for (temporary) xmp file fileXMP=shared.constructFileName(imageIn,pathOut,"xmp","") # If previous run of aWrapper was terminated by the user, a file with this # name could still be there (and this would raise an error in ExifTool) shared.removeFile(fileXMP) # Extract metadata from input image and store result in XMP format exifSysString=shared.quoteString(exifToolApp) + " " + imageIn + " -o " + fileXMP shared.printInfo("running ExifTool") exifExitStatus,exifStdOut,exifStdErr=launchSubProcess(exifSysString) # Generate Aware command line option for metadata embedding aMetadata=awareMetadataString(fileXMP) # Construct encoder command line aInput=awareInputImageString(imageIn) aOutput=awareOutputImageString(imageOut) awareSysString=(shared.quoteString(j2kDriverApp) + " " + aInput + " " + awareOptionsString + " " + aMetadata + " " + aOutput) # Run encoder, but only if ExifTool didn't give any errors. if exifExitStatus==0: shared.printInfo("running Aware j2kdriver ...") awareExitStatus,awareStdOut,awareStdErr=launchSubProcess(awareSysString) else: shared.printWarning(imageIn + " not converted because ExifTool exited with errors! \ See log file for details.") # Check if output image was really created and print info to screen # (Note that Aware can give exit code 0 even if things go seriously wrong!) jp2Created=jp2CreationInfo(imageOut) if extractMetadataFlag==True and exifExitStatus==0: # Clean up temporary file os.remove(fileXMP) # Create element object for storing conversion info conversionInfo=ET.Element('image') # Pre-format all output timeStr=time.asctime() imageIn=shared.toUTF8(os.path.abspath(imageIn)) imageOut=shared.toUTF8(os.path.abspath(imageOut)) jp2Created=str(jp2Created) exifExitStatus=str(exifExitStatus) exifStdOut=shared.toUTF8(exifStdOut) exifStdErr=shared.toUTF8(exifStdErr) awareExitStatus=str(awareExitStatus) awareStdOut=shared.toUTF8(awareStdOut) awareStdErr=shared.toUTF8(awareStdErr) # Add to element conversionInfo.appendChildTagWithText("time", timeStr) conversionInfo.appendChildTagWithText("imageIn", imageIn) conversionInfo.appendChildTagWithText("imageOut", imageOut) conversionInfo.appendChildTagWithText("jp2Created", jp2Created) conversionInfo.appendChildTagWithText("exifExitStatus", exifExitStatus) conversionInfo.appendChildTagWithText("exifStdOut", exifStdOut) conversionInfo.appendChildTagWithText("exifStdErr", exifStdErr) conversionInfo.appendChildTagWithText("awareExitStatus", awareExitStatus) conversionInfo.appendChildTagWithText("awareStdOut", awareStdOut) conversionInfo.appendChildTagWithText("awareStdErr", awareStdErr) # Return conversion info return(conversionInfo)