AWS Thinkbox Discussion Forums

Convert EXR to TGA

Can you use Draft to convert an EXR file to a TGA file with sRGB correction baked in?

You can! The file conversion is automatic, depending on the filename you specify in Draft.Image.WriteToFile( filename ). You can bake in an sRGB correction by using the LUT returned by Draft.LUT.CreateSRGB(). Here’s a minimal example:

[code]import Draft

inFile = ‘/path/to/input.exr’
outFile = ‘/path/to/output.tga’

img = Draft.Image.ReadFromFile( inFile )

lut = Draft.LUT.CreateSRGB()
lut.Apply( img )

img.WriteToFile( outFile )[/code]

You can find a bit more information on baking color transforms in Draft here: http://www.thinkboxsoftware.com/draft-baking-color-transform/

Great thanks.

Next query…

Can we Un-premultiply our image before saving it as TGA?

This would mean dividing the RGB by the Alpha…

Yes, you can use the Image.Unpremultiply() method to do so:img.Unpremultiply() img.WriteToFile( outFile )

Awesome! I like Draft! :slight_smile:

So what about setting compression to be on for TGA?

We don’t yet have compression settings exposed for saving, but it’s on our wish list. I’ll add a note that you’ve requested this feature.

Cheers,
Andrea

It’s only Run-Length-Encoding, the source code for RLE for TGAs is widely available online.

I was hoping Draft would get around the issue that the Tile Assembler for Deadline has with compressing TGA files. :frowning:

I didn’t realize that the Tile Assembler can’t write compressed TGA files. I’ll add that to our wish list for Draft.

Yeah I reported this as a bug a long time ago…

If I try writing to TIF instead can I set compression and bit-depth? I just basically need an 8bit version of the EXR with loss-less compression and unpremultiplied with Alpha.

Unfortunately no, currently we don’t expose compression or bit-depth settings for any image format.

Please add to the list :slight_smile: :stuck_out_tongue:

Is there any documentation set up showing how to get a list of all the rendered files from a deadline job?

Frame range job with elements

and

Tile Assembly job with elements

Hey Dave,

I’m assuming you’re wanting to get this information in the context of your Draft script? If so, this cookbook entry is a good base to get the info you’re looking for:
thinkboxsoftware.com/draft-u … es-recipe/

Using that technique, the properties you’d be interested in would be “OutputDirectories” and “OutputFileNames”. Obviously, the first one contains the directory where the output file is located, while the second list is the name of the files within those directories. These are both lists, since a given job can have multiple outputs, and are guaranteed to have the same amount of entries (the first filename goes with the first directory, second with the second, etc). So after getting the job property dictionary through the ‘GetDeadlineJobProperties’ utility function (see cookbook entry above), you’d get your full list of outputs files with a loop that resembles something like this:

import os
#create a list of fully-qualified file names
outputFiles = []

for i in range( 0, len( jobProps["OutputDirectories"] ) ):
	fullFileName = os.path.join( jobProps["OutputDirectories"][i], jobProps["OutputFileNames"][i] )
	outputFiles.append( fullFileName )

Keep in mind that these file names will have frame numbers swapped out for padding (usually “#”, but I believe Maya uses “?”), and these properties will only be present if Deadline is aware of the Output Location – ie, if you can “Browse to Output Location” in the Monitor, these properties should be present.

Also note that this doesn’t account for any cross-platform Path Mapping you may have; the path will be in the form of whatever OS the Job was submitted in.

If I assumed wrong, and you want the output files from a different location (Plugin, Event Plugin, command line, etc) let me know, and I’ll amend my response :slight_smile:

Cheers,

  • Jon

Thanks Jon,

Not having much success getting things up and running yet.

Looking at a slightly different approach we have a Post-Job Event script which sorts some of our files and it’d be perfect if Draft could jump in there but it seems I can’t just put

import draft

into an event script?

Did you type Draft with a lowercase or uppercase D? It should be uppercase. What was the exact error message you got? Have you been able to run any of the sample scripts? If you post your error messages, we can help you out.

Cheers,
Andrea

Unfortunately debugging an event script seems to be quite difficult as there is no log.

I’ve got a working Post-Event Script, that moves some files, If I add the following line…

import Draft

It stops working, but nowhere to see what the error is.

Trying to set up a Draft job this wasn’t working either…

[code]import Draft
import os

from DraftParamParser import *

#Sample input
deadlineRepoPath = r"\bluearc.taylorjames.com\DeadlineRepository" #Deadline repository
deadlineJobID = “999_090_000_280e7d64” #The ID of the Deadline Job to parse

#Call the utility function
jobProps = GetDeadlineJobProperties( deadlineRepoPath, deadlineJobID )

#create a list of fully-qualified file names
outputFiles = []

for i in range( 0, len( jobProps[“OutputDirectories”] ) ):
fullFileName = os.path.join( jobProps[“OutputDirectories”][i], jobProps[“OutputFileNames”][i] )
outputFiles.append( fullFileName )
outFile = (os.path.splitext(fullFileName))[0] + “.tga”

img = Draft.Image.ReadFromFile( fullFileName )
img.Unpremultiply() 
lut = Draft.LUT.CreateSRGB()

lut.Apply( img )
 
img.WriteToFile( outFile )[/code]

It looks like you’re using an older version of Draft. The GetDeadlineJobProperties() function was added in Draft Beta 14. Could you please update to a newer version of Draft and try again? If that’s not an option, please let me know, and I will send you a newer version of DraftParamParser which includes the missing function.

Thanks Paul, so updated Draft to RC3 and now that function is working, and got my Draft script working.

It would be a lot easier for our pipeline to be able to use the Post-Job Event script to get Draft to do this…

I still get the issue of adding the line ‘import Draft’ to an Event script causes it to fail to execute, but with no error message or warning… Should this work in theory?

Hey Dave,

You should be able to get this working, it’ll just require a little bit more legwork than normal :slight_smile:

The tricky part is that you have to make sure Python knows where to find the Draft libraries. Normally (ie, when using the Draft plugin), Deadline handles this for you under the hood so that you don’t ever have to worry about it, but in this case you’ll have to do it manually.

We actually use some Draft stuff in our Shotgun Event Plugin for something really similar to what you’re doing. Here’s a snippet of code from that Event Plugin that manually adds the Draft folder in the Repository to Python’s search path before doing the import, and then does an image conversion on a thumbnail:

from System.IO import *
from Deadline.Scripting import *

#first figure out where the Draft folder is on the repo
draftRepoPath = Path.Combine( RepositoryUtils.GetRootDirectory(), "Draft" )
		
if SystemUtils.IsRunningOnMac():
	draftRepoPath = Path.Combine( draftRepoPath, "Mac" )
else:
	if SystemUtils.IsRunningOnLinux():
		draftRepoPath = Path.Combine( draftRepoPath, "Linux" )
	else:
		draftRepoPath = Path.Combine( draftRepoPath, "Windows" )
			
	if SystemUtils.Is64Bit():
		draftRepoPath = Path.Combine( draftRepoPath, "64bit" )
	else:
		draftRepoPath = Path.Combine( draftRepoPath, "32bit" )
		
#import Draft and do the actual conversion
ClientUtils.LogText( "Appending '%s' to Python search path" % draftRepoPath )
if not draftRepoPath in sys.path:
	sys.path.append( draftRepoPath )
ClientUtils.LogText( "Importing Draft to perform Thumbnail conversion..."  )

import Draft

ClientUtils.LogText( "Reading in image '%s'..."  % pathToFrame )
originalImage = Draft.Image.ReadFromFile( str(pathToFrame) )
ClientUtils.LogText( "Converting image to type '%s'..."  % format )
tempPath = Path.Combine( ClientUtils.GetDeadlineTempPath(), "%s.%s" % (Path.GetFileNameWithoutExtension(pathToFrame), format) )
ClientUtils.LogText( "Writing converted image to temp path '%s'..."  % tempPath )
originalImage.WriteToFile( str(tempPath) )
ClientUtils.LogText( "Done!" )

Few things to note about this code. First, it accounts for different bitness/OSes; if your farm is homogeneous in that respect (e.g., all 64 bit Windows), you could shorten that code a lot by eliminating the cross-platform checks. Second, note that this is importing Draft directly from the Repo (i.e., over the network); that probably isn’t a problem, but I figured I’d point it out in case it is. Finally, I have a ton of ClientUtils.LogText calls in there to help with debugging any issues; calls made to LogText like this should be showing up in the Job’s Logs, let me know if they aren’t.

Cheers,

  • Jon

Thanks Jon, I’ll test that out tomorrow…

One last thing…

On my standard Draft script, how do I make it pick up the JobID of the job it is dependent on, from the Docs I assumed it would pick this up automatically or do you need to call it? That’s the last bit missing on this script which will convert EXRs to TGAs with sRGB burned in.

[code]import Draft
import os

from DraftParamParser import *

#Sample input
deadlineRepoPath = r"\bluearc.taylorjames.com\DeadlineRepository" #Deadline repository
#deadlineJobID = “999_090_000_280e7d64” #The ID of the Deadline Job to parse

#Call the utility function
jobProps = GetDeadlineJobProperties( deadlineRepoPath, deadlineJobID )

#create a list of fully-qualified file names
outputFiles = []
frameList = FrameRangeToFrames(jobProps[“FramesList”])

for i in range( 0, len( jobProps[“OutputDirectories”] ) ):
fullFileName = os.path.join( jobProps[“OutputDirectories”][i], jobProps[“OutputFileNames”][i] )
outputFiles.append( fullFileName )

for i in range( 0, len(outputFiles)):
if (os.path.splitext(outputFiles[i]))[1] == “.exr”:
for frameNumber in frameList:
inFile = ReplaceFilenameHashesWithNumber( outputFiles[i], frameNumber )
outFile = (os.path.splitext(inFile))[0] + “.tga”
img = Draft.Image.ReadFromFile( inFile )
img.Unpremultiply()
lut = Draft.LUT.CreateSRGB()
lut.Apply( img )
img.WriteToFile( outFile )[/code]

Privacy | Site terms | Cookie preferences