如何根据一个特定调整大量图像的颜色? [英] How to adjust the colors of a large number of images based on one spesific?

查看:40
本文介绍了如何根据一个特定调整大量图像的颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大量的照片,我想将它们带到相同的水平"-相同的颜色/亮度/对比度等.为此,我有一个带有黑色和黑色的初始/指南.白色颜色检查器(基本上是带有颜色的方块),我添加到所有其他照片中.

这是初始/指南

这是我制作的脚本.

请注意,我使用的是您的 png 文件,因此如果您的文件大小不同,您可能需要调整颜色采样器的坐标.

var 采样器、sampledColors、sourceCoords、targetCoords;//定义坐标以从活动源文档中采样 6 种颜色源坐标 = [[55, 318],[190, 318],[310, 318],[420, 318],[560, 318],[690, 318],];//定义坐标以从目标文档中采样目标颜色目标坐标 = [[78, 120],[206, 120],[328, 120],[453, 120],[577, 120],[709, 120],]//图书馆var Utils = Utils ||{//将 photoshop Color Sampler 添加到文档addSample:函数(坐标){返回 app.activeDocument.colorSamplers.add(coord);},//从颜色采样器读取颜色读取样本:函数(样本){返回样本颜色;},//获取颜色采样器的集合获取采样器:函数(){返回 app.activeDocument.colorSamplers;},//删除一个颜色采样器删除样本:函数(样本){样本.remove();},//RGB >YUV颜色翻译rgb2yuv:函数(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);返回 [y, u, v];},//线性变换线性:函数(X,A,B,C,D,_cut){var _cut = _cut !== 未定义?_cut : 假;var Y = (X - A)/(B - A) * (D - C) + C如果(_cut){如果 (Y > D) Y = D;如果 (Y < C) Y = C;}返回 Y;},//将活动文档颜色空间更改为 RGBdocToRgb:函数(){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);},/*** @description 在具有预定义增量的特定坐标中创建矩形选择:-7/+7 到坐标"值* @param {array} - [0] 是 X,[1] 是 Y 坐标** @return 什么都没有*/矩形选择:功能(坐标){无功增量 = 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);},/*** @description 将活动文档保存为 TIF 文件* @param {object} data - .name(无扩展名)用于名称和 data.path 用于路径** @return 什么都没有*/saveTIF:函数(数据){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 = 函数(坐标){var 颜色 = [];var 颜色,采样器;//确保文档在 rgb 中Utils.docToRgb();//对于所有坐标..for (var i = 0; i <坐标.长度; i++){//在坐标中创建一个 14x14 像素的矩形选区Utils.rectangleSelection(坐标[i]);//平均模糊它以确保颜色采样器从嘈杂的方块中采样平均颜色,因为颜色采样器没有颜色样本大小的选项activeDocument.activeLayer.applyAverage();activeDocument.selection.deselect();//广告颜色样本采样器 = Utils.addSample(坐标[i]);//读取颜色样本颜色 = Utils.readSample(sampler);//颜色被添加到 [colors]颜色.推(颜色);Utils.deleteSample(采样器);}返回颜色;};//为新文档创建渐变映射var setSamplerData = function(){var 工作文件夹;var 控制器 = 函数(原始颜色){var docs、doc、docSampler、sampledColors、gradientColors;尝试{文档 = getDocs();//要求使用文件夹}赶上 (e){返回假;}//对于所有找到的文档...for (var i = 0; i < docs.length; i++){尝试{//打开它并确保它处于 rgb 模式doc = openDocument(docs[i]);}赶上 (e){返回假;}//获取颜色框中的当前颜色采样颜色 = getSamplersData(targetCoords);//使用当前颜色位置和原始颜色为渐变映射创建一个颜色数组gradientColors = createGradientDataFromColors(originalColors, sampledColors);//创建一个渐变映射createGradient(gradientColors);//保存一个文件Utils.saveTIF({路径:workFolder + "/export",名称:activeDocument.name});}};////////////////////////////////////////////////////////////////////////////////////////这将作为一个文件夹并将返回找到的文档var getDocs = function(){var 文档;workFolder = Folder.selectDialog();if (workFolder == null) throw 'canceled';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 '文件夹中没有文件';返回文档;};//getDocs() 结束//打开一个文档并确保它处于 rgb 颜色模式var openDocument = 函数(路径){无功文档;尝试{doc = app.open(new File(path));Utils.docToRgb();返回文档;}赶上 (e){alert("无法打开" + path + "\nAborting");扔e;}};//这将创建一个渐变映射var createGradientDataFromColors = 函数(原始,采样){var 颜色 = [];var rgbOriginal, rgbSampled, positionSampled;for (var i = 0; i < original.length; i++){rgbOriginal = getRGB(original[i]);//从 SolidColor 对象中获取 [r,g,b] 数组rgbSampled = getRGB(sampled[i]);//从 SolidColor 对象中获取 [r,g,b] 数组positionSampled = Math.round(Utils.rgb2yuv(rgbSampled)[0] * 10000)/100;//从当前文档颜色中获取位置颜色.推({颜色: rgbOriginal,pos: 位置采样});}返回颜色;};//结束 createGradientDataFromColors()//这会将 rgb 从纯色转换为 [r, g 和 b] 数组var getRGB = 函数(颜色){返回 [color.rgb.red, color.rgb.green, color.rgb.blue];};//getRGB() 结束//创建一个渐变映射//颜色来自原始文档,位置来自目标文档var createGradient = 函数(数据){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();变种;for (var i = 0; i < data.length; i++){el = 数据[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);};返回控制器;};采样颜色 = getSamplersData(sourceCoords);采样器 = setSamplerData();采样器(采样颜色);

I have a large number of photos which I want to bring to the same 'level' -same colors / brightness / contrast etc. To this end I have one initial / guide with a black & white color checker (basically the squares with colors), which I added to all other photos.

This is the initial / guide https://imgur.com/a/Jlozy1e and these are some of the photos https://imgur.com/JUsKMt2 , https://imgur.com/PvqsleR , https://imgur.com/tcMROU9

As I see it the area with the little square colors (color control squares) must be the same color (hex value) in all photos in order for them to be at the same level -so I can get meaningful data from the strip below.

Is there a way to do with an automated / batch way in photoshop or some other tool?

EDIT: Note that there might be darker / lighter areas than those in the control squares which i want to preserve them (just get lighter/darker accordingly but not completely replace them with a threshold color)

解决方案

I don't know if this is possible with any advanced tool but here's my take in Photoshop. The idea is quite simple — use a gradient map to remap target colors to source values (hence this won't work on 32bit tiffs):

  1. sample source colors from an active document (source document);
  2. ask for a path with other documents to open, start to open them one by one;
  3. sample target colors and get their position for a gradient map
  4. use source colors and target positions to create a gradient map

Here's the result I got: left row are original documents with a piece of the source squares on top of them for a reference, right row are result documents with the gradient map applied and the same slice from the source doc on top (barely visible):

And here's the script I made.

Note that I was using your png files so if your files are different size you might need to adjust coordinates for color samplers.

var sampler, sampledColors, sourceCoords, targetCoords;

// defining coordinates to sample 6 colors from the active source-document
sourceCoords = [
    [55, 318],
    [190, 318],
    [310, 318],
    [420, 318],
    [560, 318],
    [690, 318],
];

// defining coordinates to sample target colors from target documents
targetCoords = [
    [78, 120],
    [206, 120],
    [328, 120],
    [453, 120],
    [577, 120],
    [709, 120],
]

// a library
var Utils = Utils ||
{

    // will add photoshop Color Sampler to document
    addSample: function(coord)
    {
        return app.activeDocument.colorSamplers.add(coord);
    },

    // reads color from a Color Sampler
    readSample: function(sample)
    {
        return sample.color;
    },

    // gets a collection of Color Samplers
    getSamplers: function()
    {
        return app.activeDocument.colorSamplers;
    },

    // deletes a Color Sampler
    deleteSample: function(sample)
    {
        sample.remove();
    },

    // RGB > YUV color translation
    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 transformation
    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;
    },

    // changes active document color space to RGB
    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);
    },

    /**
     * @description Creates a rectangle selection in a specific coordinates with a predefined delta: -7 / +7 to 'coord' values
     * @param  {array}  - [0] is X, [1] is Y coordinates
     *
     * @return nothing
     */
    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);
    },

    /**
     * @description saves an active document as a TIF file
     * @param  {object} data - .name (without extension) for a name and data.path for a path
     *
     * @return nothing
     */
    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);
    },
};

// this will get colors from the source document
var getSamplersData = function(coordinates)
{
    var colors = [];
    var color, sampler;

    // makes sure the doc is in rgb
    Utils.docToRgb();

    // for all coordinates..
    for (var i = 0; i < coordinates.length; i++)
    {
        // create a rectangular selection of 14x14 pixels in the coordinate
        Utils.rectangleSelection(coordinates[i]);

        // average blur it to make sure color sampler samples an average color from noisy square because there's no option for color sample size for Color Samplers
        activeDocument.activeLayer.applyAverage();
        activeDocument.selection.deselect();

        // ads a color sample
        sampler = Utils.addSample(coordinates[i]);

        // reads a color sample
        color = Utils.readSample(sampler);

        // color is added to [colors]
        colors.push(color);
        Utils.deleteSample(sampler);
    }
    return colors;
};

// creates gradient maps for new documents
var setSamplerData = function()
{
    var workFolder;

    var controller = function(originalColors)
    {
        var docs, doc, docSampler, sampledColors, gradientColors;

        try
        {
            docs = getDocs(); // asks for a folder to work with
        }
        catch (e)
        {
            return false;
        }

        // for all found documents...
        for (var i = 0; i < docs.length; i++)
        {
            try
            {
                // opening it and makes sure it's in rgb mode
                doc = openDocument(docs[i]);
            }
            catch (e)
            {
                return false;
            }

            // getting current colors in the color boxes
            sampledColors = getSamplersData(targetCoords);

            // create an array of color for a gradient map using current colors positions and original colors
            gradientColors = createGradientDataFromColors(originalColors, sampledColors);

            // creates a gradient map
            createGradient(gradientColors);

            // saves a file
            Utils.saveTIF(
            {
                path: workFolder + "/export",
                name: activeDocument.name
            });
        }
    };

    /////////////////////////////////////////////////////////////////////////////////////
    // this will as for a folder and will return found docs
    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()

    // opens a doc and makes sure it's in rgb color mode
    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;
        }
    };

    // this will create a gradient map 
    var createGradientDataFromColors = function(original, sampled)
    {
        var colors = [];
        var rgbOriginal, rgbSampled, positionSampled;

        for (var i = 0; i < original.length; i++)
        {
            rgbOriginal = getRGB(original[i]); // get an array of [r,g,b] from SolidColor object
            rgbSampled = getRGB(sampled[i]); // get an array of [r,g,b] from SolidColor object
            positionSampled = Math.round(Utils.rgb2yuv(rgbSampled)[0] * 10000) / 100; // getting positions from the current document colors

            colors.push(
            {
                color: rgbOriginal,
                pos: positionSampled
            });
        }

        return colors;
    }; // end of createGradientDataFromColors()

    // this will convert an rgb from Solid Color to an array of [r, g and b]
    var getRGB = function(color)
    {
        return [color.rgb.red, color.rgb.green, color.rgb.blue];
    }; // end of getRGB()

    // creates a gradient map
    // colors are from the original doc, positions are from the target docs
    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);

这篇关于如何根据一个特定调整大量图像的颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆