Javascript 在Photoshop脚本中获取一个像素的颜色

Javascript 在Photoshop脚本中获取一个像素的颜色,javascript,photoshop-script,cs4,Javascript,Photoshop Script,Cs4,我试图找出如何获得一个定义像素的颜色 在我的想象中,它应该是这样的: color = get.color.Pixel(x,y); 也许有人能帮我处理这段代码 Photoshop的JavaScript API并不像您在问题中想象的那样提供机制 您需要使用Document.colorSamplers.add([x,y])方法,然后通过其属性读取每个组件的颜色值: 以下要点说明了如何获得给定坐标的x,y的rgb或cmyk值: #目标photoshop //定义要采样的像素的x和y坐标。 var x=

我试图找出如何获得一个定义像素的颜色

在我的想象中,它应该是这样的:

color = get.color.Pixel(x,y);

也许有人能帮我处理这段代码

Photoshop的JavaScript API并不像您在问题中想象的那样提供机制

您需要使用
Document.colorSamplers.add([x,y])
方法,然后通过其属性读取每个组件的颜色值:

以下要点说明了如何获得给定坐标的
x,y
rgb
cmyk
值:

#目标photoshop
//定义要采样的像素的x和y坐标。
var x=1;
变量y=1;
//在图像中给定的x和y坐标处添加颜色采样器。
var pointSample=app.activeDocument.colorSamplers.add([(x-1),(y-1)];
//获取RGB值的数组。
变量rgb=[
pointSample.color.rgb.red,
pointSample.color.rgb.green,
pointSample.color.rgb.blue
];
//获取取整的CMYK值数组。
变量cmyk=[
数学圆(pointSample.color.cmyk.cyan),
数学圆(pointSample.color.cmyk.magenta),
数学圆(pointSample.color.cmyk.yellow),
Math.round(pointSample.color.cmyk.black)
];
//取下颜色采样器。
pointSample.remove();
//显示完整的RGB值和每个组件颜色。
警报('RGB:'+RGB)
警报('红色:'+rgb[0])
警报('绿色:'+rgb[1])
警报('蓝色:'+rgb[2])
//显示完整的CMYK值和每个组件颜色。
警报('CMYK:'+CMYK)
警报('青色:'+cmyk[0])
警报('洋红:'+cmyk[1])
警报('黄色:'+cmyk[2])
警报('黑色:'+cmyk[3])

下面是一个使用
颜色采样器的简单脚本。它被设置为返回RGB值

function PixelSampler(doc) {
    this.doc = doc
    this.doc.colorSamplers.removeAll();
    this.sampler = this.doc.colorSamplers.add([0, 0]);
}

// Return an array of R, G, B pixel values for a particular coordinate.
PixelSampler.prototype.get = function (x, y) {
    this.sampler.move([x, y]);
    const R = this.sampler.color.rgb.red;
    const G = this.sampler.color.rgb.green;
    const B = this.sampler.color.rgb.blue;
    return [R, G, B];
}

////////////////////////////////////////////////////////
/// SOME TESTS /////////////////////////////////////////
////////////////////////////////////////////////////////

const p = new PixelSampler(app.activeDocument);
alert("Pixel 0 =\n\n" + p.get(0, 0));

$.hiresTimer;
var n = 1000; //p.width * p.height;
for (var i = 0; i < n; i++) p.get(i, 0);
sec = ($.hiresTimer / 1000 / 1000);
alert("Got " + (n / 1000) + " kilopixels in " + sec.toFixed(2) + " seconds.");
功能像素采样器(doc){
this.doc=doc
this.doc.colorSamplers.removeAll();
this.sampler=this.doc.colorSamplers.add([0,0]);
}
//返回特定坐标的R、G、B像素值数组。
PixelSampler.prototype.get=函数(x,y){
这个.sampler.move([x,y]);
const R=this.sampler.color.rgb.red;
const G=this.sampler.color.rgb.green;
常量B=this.sampler.color.rgb.blue;
返回[R,G,B];
}
////////////////////////////////////////////////////////
///一些测试/////////////////////////////////////////
////////////////////////////////////////////////////////
const p=新的像素采样器(app.activeDocument);
警报(“像素0=\n\n”+p.get(0,0));
$hiresTimer;
var n=1000//p、 宽度*p.高度;
对于(var i=0;i
这在我的机器上为我提供每秒100像素的像素值

我找到并整理了一下脚本。基本上,这个想法是:

  • 将当前图像另存为原始位图
  • 读回,但在javascript方面
  • 对javascript端的像素进行所有访问
  • 这为我提供了每秒72000像素的像素值,不包括将原始数据写入磁盘并读回的开销。它还有一个额外的好处,那就是你也可以设置像素值

    // Adapted from https://community.adobe.com/t5/photoshop/get-index-of-each-pixel/td-p/10022899?page=1
    // The purpose is to query (and change) pixel values quickly.
    //
    // The secret to speed is doing everything on the script side rather than ask Photoshop to do things.
    // We use files on disk as an intermediary; on the script side, we read / write it as a binary file; on the
    // Photoshop side, we save / open it as a raw bitmap.
    //
    // Only works on RGB 8bpp images, but this could be easily extended to support others.
    function RawPixels(doc) {
        this.doc = doc;
    
        const currentActiveDoc = app.activeDocument;
    
        // Obtain the width and height in pixels of the desired document.
        const currentRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;
        app.activeDocument = doc;
        this.width = Number(doc.width.value);
        this.height = Number(doc.height.value);
        this.length = this.width * this.height;
        this.pixelData = "";
    
        // Return the ruler to its previous state.
        app.preferences.rulerUnits = currentRulerUnits;
    
        try {
            // We're going to save this document as a raw bitmap to be able to read back in the pixel values
            // themselves.
            const file = new File(Folder.temp.fsName + "/" + Math.random().toString().substr(2) + ".raw");
    
            // Set up the save action.
            // See https://helpx.adobe.com/photoshop/using/file-formats.html#photoshop_raw_format for some info,
            // and more technical at https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
            var rawFormat = new ActionDescriptor();
            rawFormat.putString(stringIDToTypeID("fileCreator"), "8BIM");
            rawFormat.putBoolean(stringIDToTypeID("channelsInterleaved"), true);
            
            var saveAction = new ActionDescriptor();
            saveAction.putObject(stringIDToTypeID("as"), stringIDToTypeID("rawFormat"), rawFormat);
            saveAction.putPath(stringIDToTypeID("in"), file);
            saveAction.putBoolean(stringIDToTypeID("copy"), false);
            executeAction(stringIDToTypeID("save"), saveAction, DialogModes.NO);
    
            // File is saved; now read it back in as raw bytes.
            file.open("r");
            file.encoding = "BINARY";
            this.pixelData = file.read();
    
            const err = file.error;
            file.close();
            file.remove();
            file = null;
            if (err) alert(err);
        }
        catch (e) { alert(e); }
    
        // Return focus to whatever the user had.
        app.activeDocument = currentActiveDoc;
    }
    
    // Calculate offset from x, y coordinates. Does not check for valid bounds.
    getOffset = function(x, y) {
        if (y == undefined) {
            // allow linear indices too
            y = Math.floor(x / this.width); 
            x = x - y * this.width;
        }
        return (y * this.width + x) * 3;
    }
    
    // Return an array of R, G, B pixel values for a particular coordinate.
    RawPixels.prototype.get = function (x, y) {
        const off = getOffset(x, y);
        const R = this.pixelData.charCodeAt(off + 0);
        const G = this.pixelData.charCodeAt(off + 1);
        const B = this.pixelData.charCodeAt(off + 2);
        return [R, G, B];
    }
    
    // Set the pixel at x, y to the values in RGB.
    RawPixels.prototype.set = function (RGB, x, y) {
        const off = getOffset(x, y);
        // note: note checking that length of p = 3!
        const R = String.fromCharCode(RGB[0]);
        const G = String.fromCharCode(RGB[1]);
        const B = String.fromCharCode(RGB[2]);
    
        this.pixelData = this.pixelData.substr(0, off) + R + G + B + this.pixelData.substr(off + 3);
    }
    
    // If any changes were made to the pixels, we need to save them to disk and have Photoshop read that file back in.
    // We do that by creating a new layer in the desired document.
    RawPixels.prototype.create_layer = function () {
        try {
            const file = new File(Folder.temp.fsName + "/" + Math.random().toString().substr(2) + ".raw");
            file.open("w");
            file.encoding = "BINARY";
            file.write(this.pixelData);
    
            const err = file.error;
            file.close();
            if (err) { file.remove(); alert(err); return; }
    
            var rawFormat = new ActionDescriptor();
            rawFormat.putInteger(stringIDToTypeID("width"), this.width);
            rawFormat.putInteger(stringIDToTypeID("height"), this.height);
            rawFormat.putInteger(stringIDToTypeID("channels"), 3);
            rawFormat.putBoolean(stringIDToTypeID("channelsInterleaved"), true);
            rawFormat.putInteger(stringIDToTypeID("depth"), 8);
    
            var openAction = new ActionDescriptor();
            openAction.putPath(stringIDToTypeID("null"), file);
            openAction.putObject(stringIDToTypeID("as"), stringIDToTypeID("rawFormat"), rawFormat);
            executeAction(stringIDToTypeID("open"), openAction, DialogModes.NO);
            file.remove();
    
            // The new active document is the file we just opened. Duplicate its contents into 
            // a new layer in our desired document, then close this temporary file.
            app.activeDocument.activeLayer.duplicate(this.doc.layers[0], ElementPlacement.PLACEBEFORE);
            const tempDoc = app.activeDocument;
            app.activeDocument = this.doc;
            this.doc.layers[0].name = "Pixels";
            app.activeDocument = tempDoc;
            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
            app.activeDocument = this.doc;
        }
        catch (e) { alert(e); }
    }
    
    ////////////////////////////////////////////////////////
    /// SOME TESTS /////////////////////////////////////////
    ////////////////////////////////////////////////////////
    
    $.hiresTimer;
    const p = new RawPixels(app.activeDocument);
    var sec = ($.hiresTimer / 1000 / 1000);
    alert("Init RawPixels in " + sec.toFixed(2) + " seconds");
    
    alert("Pixel 0 =\n\n" + p.get(0));
    var a = new Array();
    for (var i = 0; i < 100; i++) a.push(p.get(i));
    alert("Pixel 0-99 = \n\n" + a.toSource());
    
    p.set(0, [1, 200, 3]);
    alert("New Pixel 0=\n\n" + p.get(0));
    
    $.hiresTimer;
    var n = p.width * p.height;
    for (var i = 0; i < n; i++) p.get(i);
    sec = ($.hiresTimer / 1000 / 1000);
    alert("Got " + (n / 1000 / 1000) + " megapixels in " + sec.toFixed(2) + " seconds.");
    
    $.hiresTimer;
    n = 10;
    for (var i = 0; i < n; i++) p.set([255, i * 20, i * 10], 1 + i * 2);
    sec = ($.hiresTimer / 1000 / 1000);
    //alert("Set " + n + " pixels in " + sec.toFixed(2) + " seconds");
    
    p.create_layer();
    alert("New layer created  with new pixels");
    
    //改编自https://community.adobe.com/t5/photoshop/get-index-of-each-pixel/td-p/10022899?page=1
    //其目的是快速查询(和更改)像素值。
    //
    //提高速度的秘诀是在脚本方面做每件事,而不是让Photoshop去做。
    //我们使用磁盘上的文件作为中介;在脚本端,我们将其作为二进制文件读/写;上
    //在Photoshop端,我们将其保存/打开为原始位图。
    //
    //仅适用于RGB 8bpp图像,但可以轻松扩展以支持其他图像。
    函数(doc){
    this.doc=doc;
    const currentActiveDoc=app.activeDocument;
    //获取所需文档的宽度和高度(以像素为单位)。
    const currentRulerUnits=app.preferences.rulerUnits;
    app.preferences.rulerUnits=单位.PIXELS;
    app.activeDocument=doc;
    this.width=编号(doc.width.value);
    this.height=编号(doc.height.value);
    this.length=this.width*this.height;
    此.pixelData=“”;
    //将标尺恢复到以前的状态。
    app.preferences.rulerUnits=currentRulerUnits;
    试一试{
    //我们将此文档保存为原始位图,以便能够读回像素值
    //他们自己。
    常量文件=新文件(Folder.temp.fsName+“/”+Math.random().toString().substr(2)+“.raw”);
    //设置保存操作。
    //看https://helpx.adobe.com/photoshop/using/file-formats.html#photoshop_raw_format 要了解一些信息,
    //而且更技术化https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
    var rawFormat=新的ActionDescriptor();
    putString(stringIDToTypeID(“fileCreator”),“8BIM”);
    putBoolean(stringIDToTypeID(“channelsInterleaved”),true;
    var saveAction=new ActionDescriptor();
    putObject(stringIDToTypeID(“as”)、stringIDToTypeID(“rawFormat”)、rawFormat);
    saveAction.putPath(stringIDToTypeID(“in”),文件);
    saveAction.putBoolean(stringIDToTypeID(“复制”),false;
    executeAction(stringIDToTypeID(“保存”)、saveAction、DialogModes.NO);
    //文件已保存;现在将其作为原始字节读回。
    文件。打开(“r”);
    file.encoding=“BINARY”;
    this.pixelData=file.read();
    const err=file.error;
    file.close();
    file.remove();
    file=null;
    如果(错误)警报(错误);
    }
    捕获(e){警报(e);}
    //将焦点返回到用户拥有的任何内容。
    app.activeDocument=currentActiveDoc;
    }
    //计算x、y坐标的偏移量。不检查有效边界。
    getOffset=函数(x,y){
    如果(y==未定义){
    //也允许线性索引
    y=数学地板(x/此宽度);
    x=x-y*此宽度;
    }
    返回值(y*this.width+x)*