Я не знаю, возможно ли это с помощью какого-либо продвинутого инструмента, но вот мой взгляд на Photoshop. Идея довольно проста - использовать карту градиента для переназначения целевых цветов в исходные значения (следовательно, это не сработает на 32-битных форматах):
- выборка исходных цветов из активного документа (исходного документа);
- запросить путь для открытия других документов, начать открывать их один за другим;
- выбрать образцы целевых цветов и получить их положение для карты градиента
- использовать исходные цветаи целевые позиции для создания карты градиента
Вот результат, который я получил: левая строка - это исходные документы с фрагментом исходных квадратов сверху для справки, правая строка - результат-документы сприменяется карта градиента и тот же фрагмент сверху исходного документа (едва видимый):
И вот сценарий, который я сделал.
Обратите внимание, что я использовал ваши файлы png, поэтому, если ваши файлы имеют другой размер, вам может потребоваться настроить координаты для цветовых пробоотборников.
var sampler, sampledColors, sourceCoords, targetCoords;
sourceCoords = [
[55, 318],
[190, 318],
[310, 318],
[420, 318],
[560, 318],
[690, 318],
];
targetCoords = [
[78, 120],
[206, 120],
[328, 120],
[453, 120],
[577, 120],
[709, 120],
]
var Utils = Utils ||
{
addSample: function(coord)
{
return app.activeDocument.colorSamplers.add(coord);
},
readSample: function(sample)
{
return sample.color;
},
getSamplers: function()
{
return app.activeDocument.colorSamplers;
},
deleteSample: function(sample)
{
sample.remove();
},
rgb2yuv: function(rgb)
{
var r = rgb[0] / 255,
g = rgb[1] / 255,
b = rgb[2] / 255;
var y = (r * 0.299) + (g * 0.587) + (b * 0.114);
var u = (r * -0.14713) + (g * -0.28886) + (b * 0.436);
var v = (r * 0.615) + (g * -0.51499) + (b * -0.10001);
return [y, u, v];
},
linear: function(X, A, B, C, D, _cut)
{
var _cut = _cut !== undefined ? _cut : false;
var Y = (X - A) / (B - A) * (D - C) + C
if (_cut)
{
if (Y > D) Y = D;
if (Y < C) Y = C;
}
return Y;
},
docToRgb: function()
{
var desc16 = new ActionDescriptor();
desc16.putClass(charIDToTypeID('T '), charIDToTypeID('RGBM'));
desc16.putBoolean(charIDToTypeID('Fltt'), false);
desc16.putBoolean(charIDToTypeID('Rstr'), false);
executeAction(charIDToTypeID('CnvM'), desc16, DialogModes.NO);
},
rectangleSelection: function(coord)
{
var delta = 7;
var descRectangleSelection = new ActionDescriptor();
var rectSelectionRef = new ActionReference();
rectSelectionRef.putProperty(charIDToTypeID('Chnl'), charIDToTypeID('fsel'));
descRectangleSelection.putReference(charIDToTypeID('null'), rectSelectionRef);
var descCoords = new ActionDescriptor();
descCoords.putUnitDouble(charIDToTypeID('Top '), charIDToTypeID('#Pxl'), coord[1] - delta);
descCoords.putUnitDouble(charIDToTypeID('Left'), charIDToTypeID('#Pxl'), coord[0] - delta);
descCoords.putUnitDouble(charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), coord[1] + delta);
descCoords.putUnitDouble(charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), coord[0] + delta);
descRectangleSelection.putObject(charIDToTypeID('T '), charIDToTypeID('Rctn'), descCoords);
executeAction(charIDToTypeID('setd'), descRectangleSelection, DialogModes.NO);
},
saveTIF: function(data)
{
if (!new Folder(data.path).exists) new Folder(data.path).create();
var desc = new ActionDescriptor();
var descOptions = new ActionDescriptor();
descOptions.putEnumerated(charIDToTypeID('BytO'), charIDToTypeID('Pltf'), charIDToTypeID('Mcnt'));
descOptions.putEnumerated(stringIDToTypeID('layerCompression'), charIDToTypeID('Encd'), stringIDToTypeID('RLE'));
desc.putObject(charIDToTypeID('As '), charIDToTypeID('TIFF'), descOptions);
desc.putPath(charIDToTypeID('In '), new File(data.path + "/" + data.name + ".tif"));
executeAction(charIDToTypeID('save'), desc, DialogModes.NO);
},
};
var getSamplersData = function(coordinates)
{
var colors = [];
var color, sampler;
Utils.docToRgb();
for (var i = 0; i < coordinates.length; i++)
{
Utils.rectangleSelection(coordinates[i]);
activeDocument.activeLayer.applyAverage();
activeDocument.selection.deselect();
sampler = Utils.addSample(coordinates[i]);
color = Utils.readSample(sampler);
colors.push(color);
Utils.deleteSample(sampler);
}
return colors;
};
var setSamplerData = function()
{
var workFolder;
var controller = function(originalColors)
{
var docs, doc, docSampler, sampledColors, gradientColors;
try
{
docs = getDocs();
}
catch (e)
{
return false;
}
for (var i = 0; i < docs.length; i++)
{
try
{
doc = openDocument(docs[i]);
}
catch (e)
{
return false;
}
sampledColors = getSamplersData(targetCoords);
gradientColors = createGradientDataFromColors(originalColors, sampledColors);
createGradient(gradientColors);
Utils.saveTIF(
{
path: workFolder + "/export",
name: activeDocument.name
});
}
};
/////////////////////////////////////////////////////////////////////////////////////
var getDocs = function()
{
var docs;
workFolder = Folder.selectDialog();
if (workFolder == null) throw 'cancelled';
docs = workFolder.getFiles('*');
for (var i = docs.length - 1; i >= 0; i--)
{
if (docs[i] instanceof Folder) docs.splice(i, 1);
}
if (docs.length == 0) throw 'no files in the folder';
return docs;
}; // end of getDocs()
var openDocument = function(path)
{
var doc;
try
{
doc = app.open(new File(path));
Utils.docToRgb();
return doc;
}
catch (e)
{
alert("can't open " + path + "\nAborting");
throw e;
}
};
var createGradientDataFromColors = function(original, sampled)
{
var colors = [];
var rgbOriginal, rgbSampled, positionSampled;
for (var i = 0; i < original.length; i++)
{
rgbOriginal = getRGB(original[i]);
rgbSampled = getRGB(sampled[i]);
positionSampled = Math.round(Utils.rgb2yuv(rgbSampled)[0] * 10000) / 100;
colors.push(
{
color: rgbOriginal,
pos: positionSampled
});
}
return colors;
}; // end of createGradientDataFromColors()
var getRGB = function(color)
{
return [color.rgb.red, color.rgb.green, color.rgb.blue];
}; // end of getRGB()
var createGradient = function(data)
{
var descGradMap = new ActionDescriptor();
var referenceMap = new ActionReference();
referenceMap.putClass(charIDToTypeID('AdjL'));
descGradMap.putReference(charIDToTypeID('null'), referenceMap);
var desc5 = new ActionDescriptor();
var desc6 = new ActionDescriptor();
var desc7 = new ActionDescriptor();
desc7.putEnumerated(charIDToTypeID('GrdF'), charIDToTypeID('GrdF'), charIDToTypeID('CstS'));
desc7.putDouble(charIDToTypeID('Intr'), 4096.000000);
var list1 = new ActionList();
var el;
for (var i = 0; i < data.length; i++)
{
el = data[i];
var descTemp = new ActionDescriptor();
var descColor = new ActionDescriptor();
descColor.putDouble(charIDToTypeID('Rd '), el.color[0]);
descColor.putDouble(charIDToTypeID('Grn '), el.color[1]);
descColor.putDouble(charIDToTypeID('Bl '), el.color[2]);
descTemp.putObject(charIDToTypeID('Clr '), charIDToTypeID('RGBC'), descColor);
descTemp.putEnumerated(charIDToTypeID('Type'), charIDToTypeID('Clry'), charIDToTypeID('UsrS'));
descTemp.putInteger(charIDToTypeID('Lctn'), Utils.linear(el.pos, 0, 100, 0, 4096));
descTemp.putInteger(charIDToTypeID('Mdpn'), 50);
list1.putObject(charIDToTypeID('Clrt'), descTemp);
}
desc7.putList(charIDToTypeID('Clrs'), list1);
var list2 = new ActionList();
var desc12 = new ActionDescriptor();
desc12.putUnitDouble(charIDToTypeID('Opct'), charIDToTypeID('#Prc'), 100.000000);
desc12.putInteger(charIDToTypeID('Lctn'), 0);
desc12.putInteger(charIDToTypeID('Mdpn'), 50);
list2.putObject(charIDToTypeID('TrnS'), desc12);
var desc13 = new ActionDescriptor();
desc13.putUnitDouble(charIDToTypeID('Opct'), charIDToTypeID('#Prc'), 100.000000);
desc13.putInteger(charIDToTypeID('Lctn'), 4096);
desc13.putInteger(charIDToTypeID('Mdpn'), 50);
list2.putObject(charIDToTypeID('TrnS'), desc13);
desc7.putList(charIDToTypeID('Trns'), list2);
desc6.putObject(charIDToTypeID('Grad'), charIDToTypeID('Grdn'), desc7);
desc5.putObject(charIDToTypeID('Type'), charIDToTypeID('GdMp'), desc6);
descGradMap.putObject(charIDToTypeID('Usng'), charIDToTypeID('AdjL'), desc5);
executeAction(charIDToTypeID('Mk '), descGradMap, DialogModes.NO);
};
return controller;
};
sampledColors = getSamplersData(sourceCoords);
sampler = setSamplerData();
sampler(sampledColors);