with this script in photoshop For MAC:
Chris Cox wrote:
The file extensions are written by the export plugin. (which incidentally has a comment that two studios wanted all caps extensions, but I failed to write down which ones in the comments)
To change the filenames, you'd want to add something at the end of doExportLUTs() that uses the supplied path and substitutes the desired extensions, then renames the file.
Thank you
// Export Color Lookup Tables automation in JavaScript
//
//
// IN_PROGRESS - why can't ColorSync Utility open any profile with a grid of 160 or larger?
// 150 works, 160 fails -- sent samples in email to Apple on Nov 8, 2013; they are investigating
// DEFERRED - right to left filenames (Arabic) come out wrong because of appending "RGB" and file extensions
// This seems to be a bug in JavaScript's handing of strings, not sure we can solve it easily.
// It might possibly be handled by checking bidi markers in UTF8 stream and adding custom handling for appending text/extensions.
/*
@@@BUILDINFO@@@ ExportColorLookupTables.jsx 1.0.0.0
*/
/*
// BEGIN__HARVEST_EXCEPTION_ZSTRING
<javascriptresource>
<name>$$$/JavaScripts/ExportColorLookupTables/Menu=Color Lookup Tables...</name>
<menu>export</menu>
<enableinfo>true</enableinfo>
<eventid>9AA9D7D6-C209-494A-CC01-4E7D926DA642</eventid>
</javascriptresource>
// END__HARVEST_EXCEPTION_ZSTRING
*/
#target photoshop
const appUIState = app.displayDialogs;
app.displayDialogs = DialogModes.NO; // suppress all app dialogs
app.bringToFront(); // make Photoshop the frontmost app, just in case
// on localized builds we pull the $$$/Strings from a .dat file
$.localize = true;
// from Terminology.jsx
const classApplication = app.charIDToTypeID('capp');
const classProperty = app.charIDToTypeID('Prpr');
const enumTarget = app.charIDToTypeID('Trgt');
const eventGet = app.charIDToTypeID('getd');
const eventSet = app.charIDToTypeID('setd');
const kcolorSettingsStr = app.stringIDToTypeID("colorSettings");
const kDither = app.charIDToTypeID('Dthr');
const keyTo = app.charIDToTypeID('T ');
const typeNULL = app.charIDToTypeID('null');
const typeOrdinal = app.charIDToTypeID('Ordn');
const kFloatWindowStr = app.stringIDToTypeID("floatWindow");
const typePurgeItem = app.charIDToTypeID('PrgI');
const enumClipboard = app.charIDToTypeID('Clpb');
const eventPurge = app.charIDToTypeID('Prge');
const keyExportLUT = app.charIDToTypeID( "lut " );
const keyFilePath = app.charIDToTypeID( 'fpth' );
const keyDescription = app.charIDToTypeID( 'dscr' );
const keyCopyright = app.charIDToTypeID( 'Cpyr' );
const keyDataPoints = app.charIDToTypeID( 'gPts' );
const keyWriteICC = app.charIDToTypeID( 'wICC' );
const keyWrite3DL = app.charIDToTypeID( 'w3DL' );
const keyWriteCUBE = app.charIDToTypeID( 'wCUB' );
const keyWriteCSP = app.charIDToTypeID( 'wCSP' );
const kScriptOptionsKey = "9AA9D7D6-C209-494A-CC01-4E7D926DA642"; // same as eventID above
const sGridMin = 7; // these must match the slider range defined in the dialog layout
const sGridMax = 256;
const sGridDefault = 32;
// our baseline UI configuration info
var gSaveFilePath = ""; // overwritten by document path
var gDescription = ""; // overwritten by document name
var gCopyright = ""; // "Adobe Systems Inc., All Rights Reserved";
var gGridPoints = sGridDefault;
var gDoSaveICCProfile = true;
var gDoSave3DL = true;
var gDoSaveCUBE = true;
var gDoSaveCSP = true;
gScriptResult = undefined;
// start doing the work...
main();
app.displayDialogs = appUIState; // restore original dialog state
gScriptResult; // must be the last thing - this is returned as the result of the script
///////////////////////////////////////////////////////////////////////////////
function readOptionsFromDescriptor( d )
{
if (!d)
return;
if (d.hasKey(keyFilePath))
gSaveFilePath = d.getString( keyFilePath ); // will be overridden by UI
if (d.hasKey(keyDescription))
gDescription = d.getString( keyDescription ); // will be overridden always
if (d.hasKey(keyCopyright))
gCopyright = d.getString( keyCopyright );
if (d.hasKey(keyDataPoints))
{
var temp = d.getInteger( keyDataPoints );
if (temp >= sGridMin && temp <= sGridMax)
gGridPoints = temp;
}
if (d.hasKey(keyWriteICC))
gDoSaveICCProfile = d.getBoolean( keyWriteICC );
if (d.hasKey(keyWrite3DL))
gDoSave3DL = d.getBoolean( keyWrite3DL );
if (d.hasKey(keyWriteCUBE))
gDoSaveCUBE = d.getBoolean( keyWriteCUBE );
if (d.hasKey(keyWriteCSP))
gDoSaveCSP = d.getBoolean( keyWriteCSP );
}
function createDescriptorFromOptions()
{
var desc = new ActionDescriptor();
desc.putString( keyFilePath, gSaveFilePath ); // will be overridden by UI
desc.putString( keyDescription, gDescription ); // will always be overridden by document name
desc.putString( keyCopyright, gCopyright );
desc.putInteger( keyDataPoints, gGridPoints );
desc.putBoolean( keyWriteICC, gDoSaveICCProfile );
desc.putBoolean( keyWrite3DL, gDoSave3DL );
desc.putBoolean( keyWriteCUBE, gDoSaveCUBE );
desc.putBoolean( keyWriteCSP, gDoSaveCSP );
return desc;
}
function doExportUI()
{
// DEFERRED - it might be nice to be able to run without UI
// Right now we can't, but someone could modify the script if they so desire
const sDescription = localize("$$$/AdobeScript/Export3DLUT/Description=Description:");
const sCopyright = localize("$$$/AdobeScript/Export3DLUT/Copyright=Copyright:");
const sQuality = localize("$$$/AdobeScript/Export3DLUT/Quality=Quality");
const sGridPoints = localize("$$$/AdobeScript/Export3DLUT/GridPoints=Grid Points:");
const sFormatsToSave = localize("$$$/AdobeScript/Export3DLUT/Formats=Formats");
const sOpenButton = localize("$$$/JavaScripts/psx/OK=OK");
const sCancelButton = localize("$$$/JavaScripts/psx/Cancel=Cancel");
const strTextInvalidType = localize("$$$/JavaScripts/Export3DLUT/InvalidType=Invalid numeric value. Default value inserted.");
const strTextInvalidNum = localize("$$$/JavaScripts/Export3DLUT/InvalidNum=A number between 7 and 256 is required. Closest value inserted.");
const strNoExportsSelected = localize("$$$/JavaScripts/Export3DLUT/NoExportTypesSelected=No export types were selected.");
const strExportPrompt = localize("$$$/JavaScripts/Export3DLUT/ExportColorLookup=Export Color Lookup");
const strUntitledLUT = localize("$$$/JavaScripts/Export3DLUT/UntitledLUTFilename=untitled.lut");
const sSaveICC = localize("$$$/AdobeScript/Export3DLUT/ICCProfile=ICC Profile");
// these are not localized, since they refer to file format extensions
const sSave3DL = "3DL";
const sSaveCUBE = "CUBE";
const sSaveCSP = "CSP";
// strings similar to JPEG quality
const sPoor = localize("$$$/AdobeScript/Export3DLUT/Poor=Poor");
const sLow = localize("$$$/AdobeScript/Export3DLUT/Low=Low");
const sMedium = localize("$$$/AdobeScript/Export3DLUT/Medium=Medium");
const sHigh = localize("$$$/AdobeScript/Export3DLUT/High=High");
const sMaximum = localize("$$$/AdobeScript/Export3DLUT/Maximum=Maximum");
const ui = // dialog resource object
"dialog { \
orientation: 'row', \
gp: Group { \
orientation: 'column', alignment: 'fill', alignChildren: 'fill', \
description: Group { \
orientation: 'row', alignment: 'fill', alignChildren: 'fill', \
st: StaticText { text:'Description:' }, \
et: EditText { characters: 30, properties:{multiline:false}, text:'<your description here>' } \
}, \
copyright: Group { \
orientation: 'row', alignment: 'fill', alignChildren: 'fill', \
st: StaticText { text:'Copyright:' }, \
et: EditText { characters: 30, properties:{multiline:false}, text:'<your copyright here>' } \
}, \
qual: Panel { \
text: 'Quality', \
orientation: 'column', alignment: 'fill', alignChildren: 'fill', \
g2: Group { \
st: StaticText { text:'Grid Points:' }, \
et: EditText { characters:4, justify:'right' } \
drp: DropDownList {alignment:'right'} \
}, \
sl: Slider { minvalue:7, maxvalue:256, value: 32 }, \
}, \
options: Panel { \
text: 'Formats', \
orientation: 'column', alignment: 'fill', alignChildren: 'left', \
ck3DL: Checkbox { text:'3DL', value:true }, \
ckCUBE: Checkbox { text:'CUBE', value:true } \
ckCSP: Checkbox { text:'CSP', value:true } \
ckICC: Checkbox { text:'ICC Profile', value:true } \
}, \
}, \
gButtons: Group { \
orientation: 'column', alignment: 'top', alignChildren: 'fill', \
okBtn: Button { text:'Ok', properties:{name:'ok'} }, \
cancelBtn: Button { text:'Cancel', properties:{name:'cancel'} } \
} \
}";
const titleStr = localize("$$$/AdobeScript/Export3DLUT/DialogTitle/ExportColorLookupTables=Export Color Lookup Tables");
var win = new Window (ui, titleStr ); // new window object with UI resource
// THEORETICALLY match our dialog background color to the host application
win.graphics.backgroundColor = win.graphics.newBrush (win.graphics.BrushType.THEME_COLOR, "appDialogBackground");
// poor, low, medium, high, max
var MenuQualityToGridPoints = [ 8, 16, 32, 64, 256 ];
function GridPointsToQualityMenuIndex( num )
{
var menu = MenuQualityToGridPoints;
var menuItems = menu.length;
if (num <= menu[0])
return 0;
if (num >= menu[ menuItems-1 ])
return (menuItems-1);
for (var i = 0; i < (menuItems-1); ++i)
{
if ((num >= menu[i]) && (num < menu[i+1]))
return i;
}
return 0; // just in case of a logic failure
}
// insert our localized strings
var drop = win.gp.qual.g2.drp; // for easier typing
drop.add('item', sPoor ); // 0
drop.add('item', sLow ); // 1
drop.add('item', sMedium ); // 2
drop.add('item', sHigh ); // 3
drop.add('item', sMaximum ); // 4
drop.selection = drop.items[2]; // Medium
win.gp.description.st.text = sDescription;
win.gp.copyright.st.text = sCopyright;
win.gp.qual.text = sQuality;
win.gp.qual.g2.st.text = sGridPoints;
win.gp.options.text = sFormatsToSave;
win.gp.options.ck3DL.text = sSave3DL;
win.gp.options.ckCUBE.text = sSaveCUBE;
win.gp.options.ckCSP.text = sSaveCSP;
win.gp.options.ckICC.text = sSaveICC;
win.gButtons.okBtn.text = sOpenButton;
win.gButtons.cancelBtn.text = sCancelButton;
// set starting parameters
win.gp.description.et.text = gDescription;
win.gp.copyright.et.text = gCopyright;
win.gp.options.ckICC.value = gDoSaveICCProfile;
win.gp.options.ck3DL.value = gDoSave3DL;
win.gp.options.ckCUBE.value = gDoSaveCUBE;
win.gp.options.ckCSP.value = gDoSaveCSP;
// global flag/hack to keep the UI pretty
var gGlobalPreventChanges = false;
with (win.gp.qual)
{
sl.value = gGridPoints;
g2.et.text = gGridPoints;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(gGridPoints) ];
// global flag is ugly, but recursive change calls are uglier
g2.et.onChange = function () { if (gGlobalPreventChanges) { return; }
gGlobalPreventChanges = true;
var val = Number(this.text);
this.parent.parent.sl.value = val;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(val) ];
gGlobalPreventChanges = false; };
sl.onChanging = function () { if (gGlobalPreventChanges) { return; }
gGlobalPreventChanges = true;
var val = Math.floor(this.value);
this.parent.g2.et.text = val;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(val) ];
gGlobalPreventChanges = false; };
};
// DEFERRED - we should also set the value if the same menu item is selected again (reset)
// but the JSX toolkit doesn't support that
drop.onChange = function()
{
if (gGlobalPreventChanges) { return; }
gGlobalPreventChanges = true;
var theSelection = this.selection.text;
if (theSelection != null) { // only change if selection made
var theSelectionIndex = this.selection.index;
var newGridPoints = MenuQualityToGridPoints[ theSelectionIndex ];
win.gp.qual.g2.et.text = newGridPoints;
win.gp.qual.sl.value = newGridPoints;
}
gGlobalPreventChanges = false;
};
win.onShow = function ()
{
this.qual.sl.size.width = 128;
this.layout.layout(true);
}
win.gButtons.cancelBtn.onClick = function () { this.window.close(2); };
// validate inputs when the user hits OK
var gInAlert = false;
win.gButtons.okBtn.onClick = function ()
{
if (gInAlert == true)
{
gInAlert = false;
return;
}
var gridText = win.gp.qual.g2.et.text;
var w = Number(gridText);
var inputErr = false;
if ( isNaN( w ) )
{
if ( DialogModes.NO != app.playbackDisplayDialogs )
{
gInAlert = true;
alert( strTextInvalidType );
gInAlert = false;
}
win.gp.qual.g2.et.text = sGridDefault;
win.gp.qual.sl.value = sGridDefault;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(sGridDefault) ];
return false;
}
if ( (w < sGridMin) || (w > sGridMax) )
{
if ( DialogModes.NO != app.playbackDisplayDialogs )
{
gInAlert = true;
alert( strTextInvalidNum );
gInAlert = false;
}
}
if ( w < sGridMin)
{
inputErr = true;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(sGridMin) ];
win.gp.qual.g2.et.text = sGridMin;
win.gp.qual.sl.value = sGridMin;
return false;
}
if ( w > sGridMax)
{
inputErr = true;
drop.selection = drop.items[ GridPointsToQualityMenuIndex(sGridMax) ];
win.gp.qual.g2.et.text = sGridMax;
win.gp.qual.sl.value = sGridMax;
return false;
}
if (inputErr == false)
{
win.close(true);
}
return;
}
win.center(); // move to center the dialog
var ret = win.show(); // dialog display
if (2 == ret)
return false; // user cancelled
// user hit OK, copy values from dialog
gDescription = win.gp.description.et.text;
gCopyright = win.gp.copyright.et.text;
gGridPoints = win.gp.qual.sl.value;
gDoSave3DL = win.gp.options.ck3DL.value;
gDoSaveCUBE = win.gp.options.ckCUBE.value;
gDoSaveCSP = win.gp.options.ckCSP.value;
gDoSaveICCProfile = win.gp.options.ckICC.value;
// if no files are going to be saved, then we have zero work to do
if ((false == gDoSaveICCProfile) && (false == gDoSave3DL) &&
(false == gDoSaveCUBE) && (false == gDoSaveCSP) )
{
// tell the user that no formats were selected
alert( strNoExportsSelected );
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return false;
}
// prompt user for directory and output base filename
// default to directory and filename of current document
var currentDocumentPath
try
{
// if the file has no path (not saved), then this throws
var documentPath = app.activeDocument.fullName.fsName; // Get the OS friendly file path and name
documentPath = documentPath.replace(/\....$/,''); // remove extension, if there is one
documentPath = documentPath + ".lut"; // add dummy extension
currentDocumentPath = File ( documentPath );
}
catch (e)
{
// if there was no document path, default to user's home directory
var defaultName = "~/" + strUntitledLUT;
currentDocumentPath = File(defaultName);
}
var fname = currentDocumentPath.saveDlg(strExportPrompt);
if (fname == null)
return false;
gSaveFilePath = fname.fsName;
return true;
}
function doExportLUTs( path )
{
const keyUsing = charIDToTypeID( 'Usng' );
const eventExport = charIDToTypeID( 'Expr' );
var desc = new ActionDescriptor();
var desc2 = new ActionDescriptor();
desc2.putString( keyFilePath, path );
desc2.putString( keyDescription, gDescription );
desc2.putInteger( keyDataPoints, gGridPoints );
// assemble the full copyright string, if needed
var copyrightAssembled = gCopyright;
if (gCopyright != "")
{
var theDate = new Date();
// the year is from 1900 ????
var theYear = (theDate.getYear() + 1900).toString();
// Localization team says to just use the year
var dateString = theYear;
copyrightAssembled = localize("$$$/JavaScripts/Export3DLUT/Copyright=(C) Copyright ") + dateString + " " + gCopyright;
}
desc2.putString( keyCopyright, copyrightAssembled );
// select output format
desc2.putBoolean( keyWriteICC, gDoSaveICCProfile );
desc2.putBoolean( keyWrite3DL, gDoSave3DL );
desc2.putBoolean( keyWriteCUBE, gDoSaveCUBE );
desc2.putBoolean( keyWriteCSP, gDoSaveCSP );
desc.putObject( keyUsing, keyExportLUT, desc2 );
try
{
var resultDesc = executeAction( eventExport, desc, DialogModes.NO );
}
catch (e)
{
if ( e.number != 8007 ) { // don't report error on user cancel
var str = localize("$$$/JavaScripts/Export3DLUT/ExportLUTFailed=Unable to run the Export Color Lookup plugin because ");
alert( str + e + " : " + e.line );
}
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return false;
}
return true;
}
function doRenderGrid( points )
{
// call the grid rendering plugin to do the work
const keyRenderGrid = charIDToTypeID( "3grd" );
const keyDataPoints2 = charIDToTypeID( 'grdP' );
var args = new ActionDescriptor();
args.putInteger( keyDataPoints2, points);
try
{
var result = executeAction( keyRenderGrid, args, DialogModes.NO );
}
catch (e)
{
if ( e.number != 8007 ) { // don't report error on user cancel
var str = localize("$$$/JavaScripts/Export3DLUT/RenderGridFailed=Unable to render color grid because ");
alert( str + e + " : " + e.line );
}
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return false;
}
return true;
}
function resizeDocumentInPixels( width, height )
{
var myDocument = app.activeDocument;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
myDocument.resizeCanvas( width, height, AnchorPosition.MIDDLECENTER)
app.preferences.rulerUnits = originalRulerUnits;
}
function GetColorSettings()
{
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( classProperty, kcolorSettingsStr );
ref1.putEnumerated( classApplication, typeOrdinal, enumTarget );
desc1.putReference( typeNULL, ref1 );
var result = executeAction( eventGet, desc1, DialogModes.NO );
var desc2 = result.getObjectValue( kcolorSettingsStr );
return desc2;
}
function GetColorConversionDitherState()
{
var settings = GetColorSettings();
if (settings.hasKey(kDither))
return settings.getBoolean( kDither );
else
return null;
}
function ConvertTo16Bit()
{
const eventConvertMode = charIDToTypeID( 'CnvM' );
const keyDepth = charIDToTypeID( 'Dpth' );
var modeDesc16Bit = new ActionDescriptor();
modeDesc16Bit.putInteger( keyDepth, 16 );
var result = executeAction( eventConvertMode, modeDesc16Bit, DialogModes.NO );
}
// state = true or false
function SetColorConversionDither( state )
{
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( classProperty, kcolorSettingsStr );
ref1.putEnumerated( classApplication, typeOrdinal, enumTarget );
desc1.putReference( typeNULL, ref1 );
var desc2 = new ActionDescriptor();
desc2.putBoolean( kDither, state );
desc1.putObject( keyTo, kcolorSettingsStr, desc2 );
executeAction( eventSet, desc1, DialogModes.NO );
}
function PurgeClipboard()
{
var desc1 = new ActionDescriptor();
desc1.putEnumerated( typeNULL, typePurgeItem, enumClipboard );
var result = executeAction( eventPurge, desc1, DialogModes.NO );
}
// This helps us avoid resizing existing document views in tabbed document mode.
// This is new functionality, and will not work in older Photoshop versions.
function MoveDocumentToNewWindow()
{
var desc1 = new ActionDescriptor();
var result = executeAction( kFloatWindowStr, desc1, DialogModes.NO );
}
function main()
{
try
{
var tempDoc = null;
var tempDoc2 = null;
// do basic troubleshooting first
// make sure there is a document
if (!app.activeDocument)
{
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return;
}
// check the document mode
var mode = app.activeDocument.mode;
if (mode != DocumentMode.RGB
&& mode != DocumentMode.LAB
&& mode != DocumentMode.CMYK)
{
var str = localize("$$$/JavaScripts/Export3DLUT/UnsupportedColorMode=Could not export Color Lookup Tables because only RGB, LAB, and CMYK color modes are supported.");
alert(str);
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return;
}
// check the document depth, for safety
var depth = app.activeDocument.bitsPerChannel; // an object, not a number - why? I have no idea...
var bitsPerChannel = 1;
if (depth == BitsPerChannelType.EIGHT)
bitsPerChannel = 8;
else if (depth == BitsPerChannelType.SIXTEEN)
bitsPerChannel = 16;
else if (depth == BitsPerChannelType.THIRTYTWO)
bitsPerChannel = 32;
else
{
var str = localize("$$$/JavaScripts/Export3DLUT/UnsupportedImageDepth=Could not export Color Lookup Tables because only 8, 16, and 32 bits/channel are supported.");
alert(str);
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return;
}
// Check layer types: background plus adjustments only
// For now, don't check each layer - a multiply solid layer still works as a color adjustment, as does selective blending
// Users will get odd results from other layer types (layer masks, pixel layers, etc.)
try
{
app.activeDocument.backgroundLayer.visible = true;
}
catch (e)
{
if (activeDocument.layers.length == 1)
alert( localize("$$$/JavaScripts/Export3DLUT/NoAdjustmentLayers=Could not export Color Lookup Tables because this document has no adjustment layers.") );
else
alert( localize("$$$/JavaScripts/Export3DLUT/NoBackground=Could not export Color Lookup Tables because this document has no background.") );
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return;
}
// look for last used params via Photoshop registry, getCustomOptions will throw if none exist
try
{
var desc = app.getCustomOptions(kScriptOptionsKey);
readOptionsFromDescriptor( desc );
}
catch(e)
{
// it's ok if we don't have any existing options, continue with defaults
}
// set some values from the document
gDescription = app.activeDocument.name;
// ask the user for options, bail if they cancel at any point
if ( doExportUI() == false)
{
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
return;
}
// we're good to go, so save our parameters for next time
app.putCustomOptions(kScriptOptionsKey, createDescriptorFromOptions() );
// remove file extension from filePath, if there is one
gSaveFilePath = gSaveFilePath.replace(/\....$/,'');
// calculate the size of image we need
var width = gGridPoints * gGridPoints;
var height = gGridPoints;
if (mode == DocumentMode.CMYK)
height = gGridPoints*gGridPoints;
// duplicate the user document so we don't mess it up in any way
tempDoc = app.activeDocument.duplicate("temporary");
// make the temporary document active
app.activeDocument.name = tempDoc;
// to avoid resizing existing document views in tabbed mode
MoveDocumentToNewWindow();
// convert 8 bit documents to 16 bit/channel for improved quality of merged adjustments
if (bitsPerChannel == 8)
{
ConvertTo16Bit();
depth = BitsPerChannelType.SIXTEEN;
}
// resize the temporary canvas to our target size
resizeDocumentInPixels( width, height )
// select background layer
tempDoc.activeLayer = tempDoc.backgroundLayer;
// render lookup base grid
var worked = doRenderGrid( gGridPoints );
if (worked != true)
{
tempDoc.close( SaveOptions.DONOTSAVECHANGES );
return; // error should have already been shown, and there is not much we can do
}
// do not flatten here -- the export automatically gets flattened data
// and we may need layers for LAB->RGB conversion below
// export the chosen formats
worked = doExportLUTs( gSaveFilePath );
if (worked != true)
{
tempDoc.close( SaveOptions.DONOTSAVECHANGES );
return; // error should have already been shown, and there is not much we can do
}
// for LAB documents to export 3DLUT (which are inherently RGB), we have to do additional work
// As a bonus, this works for CMYK as well!
if ( mode != DocumentMode.RGB )
{
var filePath = gSaveFilePath + "RGB";
var oldDitherState = GetColorConversionDitherState();
try
{
SetColorConversionDither(false);
const targetProfileName = "sRGB IEC61966-2.1";
// new document temp2 in sRGB, matching depth of original
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
tempDoc2 = app.documents.add( width, gGridPoints, 72, "temp2",
NewDocumentMode.RGB, DocumentFill.WHITE,
1.0, depth, targetProfileName );
app.preferences.rulerUnits = originalRulerUnits;
// make the new doc active
app.activeDocument.name = tempDoc2;
// to avoid resizing existing document views in tabbed mode
MoveDocumentToNewWindow();
// insert grid
worked = doRenderGrid( gGridPoints );
if (worked == true)
{
tempDoc2.selection.selectAll();
tempDoc2.activeLayer = tempDoc2.backgroundLayer;
tempDoc2.selection.copy();
tempDoc2.close( SaveOptions.DONOTSAVECHANGES );
tempDoc2 = null;
// make sure temp1 is active
app.activeDocument.name = tempDoc;
// resize for RGB grid
resizeDocumentInPixels( width, gGridPoints );
tempDoc.selection.selectAll();
tempDoc.paste(true);
PurgeClipboard(); // so we don't leave an odd, large item on the clipboard
tempDoc.selection.deselect();
tempDoc.flatten();
// convert temp1 to sRGB
tempDoc.convertProfile( targetProfileName, Intent.RELATIVECOLORIMETRIC, true, false );
// export the chosen formats
worked = doExportLUTs( filePath );
// at this point we still have to clean up, even if the call failed, so fall through
}
else
{
tempDoc2.close( SaveOptions.DONOTSAVECHANGES );
}
}
catch (e)
{
if ( e.number != 8007 ) { // don't report error on user cancel
var str = localize("$$$/JavaScripts/Export3DLUT/UnableToConvertRGB=Unable to convert image to RGB because ");
alert( str + e + " : " + e.line );
}
if (tempDoc2 != null) tempDoc2.close( SaveOptions.DONOTSAVECHANGES );
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
}
// always reset the dither state
SetColorConversionDither( oldDitherState );
PurgeClipboard(); // so we don't leave an odd, large item on the clipboard
} // if not RGB
// always close temp document without saving
tempDoc.close( SaveOptions.DONOTSAVECHANGES );
}
catch (e)
{
if ( e.number != 8007 ) { // don't report error on user cancel
var str = localize("$$$/JavaScripts/Export3DLUT/UnableToExport=Unable to export LUT because ");
alert( str + e + " : " + e.line );
}
// always close temp document without saving
if (tempDoc != null) tempDoc.close( SaveOptions.DONOTSAVECHANGES );
gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
}
}