Skip to main content
Participant
May 25, 2020
Answered

複数のアンカーポイントのハンドルをリセットする方法

  • May 25, 2020
  • 3 replies
  • 1347 views

選択した複数のアンカーポイントのハンドルをすべてリセットする方法を探しています。

 

図形画像を選択範囲からパス化をして図形のシェイプをつくった時、

アンカーポイントのハンドルが変な状態で入っていたりして選択元の図形画像の

形に添っていないときがあります。

ですので、すべてのアンカーポイントを「アンカーポイント切り替えツール」で

選択してハンドルのリセットをして形状を整えているのですが、アンカーポイントが多いととても手間です。

 

複数のアンカーポイントのハンドルをリセットする方法はありますか?

This topic has been closed for replies.
Correct answer c.pfaffenbichler

 

// retract all bezier handles of the selected path;
// 2020, use it at your own risk;
if (app.documents.length > 0) {activeDocument.suspendHistory("reset handles", "main ()")};
////////////////////////////////////
function main () {
var thePathIndex = selectedPath2020 ();
if (thePathIndex != undefined) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var thePath = collectPathInfoFromDesc2020 (activeDocument, thePathIndex[0]);
if (thePath.length > 0) {
var originalResolution = activeDocument.resolution;
activeDocument.resizeImage (null, null, 72, ResampleMethod.NONE);
////////////////////////////////////
var theArray2 = new Array;
for (var m = 0; m < thePath.length; m++) {
var thisSubPath = thePath[m];
var thisLength = thisSubPath.length;
var aNewArray = new Array;
for (var n = 0; n < thisSubPath.length-2; n++) {
var thisPoint = thisSubPath[n];
aNewArray.push([thisPoint[0], thisPoint[0], thisPoint[0], thisPoint[3], thisPoint[4]])
};
aNewArray.push(thisSubPath[thisLength-2], thisSubPath[thisLength-1]);
theArray2.push(aNewArray)
};
////////////////////////////////////
// if the path is a vector mask;
if (thePathIndex[1] == 1953) {
var thePath = changeSelectedPath2020(theArray2);
} else {
deselectLayers();
var thePath = changeSelectedPath2020(theArray2);
};
////////////////////////////////////
// reset;
app.preferences.rulerUnits = originalRulerUnits;
activeDocument.resizeImage (null, null, originalResolution, ResampleMethod.NONE);
}
};
};
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2020 (myDocument, thePath) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
ref.putIndex(cTID("Path"), thePath);
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
    var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
    var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
    switch (operation1) {
        case 1097098272:
        var operation = 1097098272 //cTID('Add ');
        break;
        case 1398961266:
        var operation = 1398961266 //cTID('Sbtr');
        break;
        case 1231975538:
        var operation = 1231975538 //cTID('Intr');
        break;
        default:
//		case 1102:
        var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
        break;
        };
// for subpathitem’s count;
    for (var n = 0; n < listKey.count; n++) {
        theArray.push(new Array);
        var points = listKey.getObjectValue(n).getList(sTID('points'));
        try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
        catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
        for (var o = 0; o < points.count; o++) {
            var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
            var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
            var thisPoint = [anchor];
            try {
                var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
                var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(leftDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
                var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(rightDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
                thisPoint.push(smoothOr)
                }
            catch (e) {thisPoint.push(false)};
            theArray[theArray.length - 1].push(thisPoint);
            };
        theArray[theArray.length - 1].push(closed);
        theArray[theArray.length - 1].push(operation);
        };
    };
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// change a path based on collectPathInfoFromDesc2012-array //////
function changeSelectedPath2020(theArray) {
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
// thanks to xbytor;
    cTID = function(s) { return app.charIDToTypeID(s); };
    sTID = function(s) { return app.stringIDToTypeID(s); };
        var desc1 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putEnumerated( cTID('Path'), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
        desc1.putReference(sTID('null'), ref1);
        var list1 = new ActionList();
    for (var m = 0; m < theArray.length; m++) {
        var thisSubPath = theArray[m];
        var desc2 = new ActionDescriptor();
        desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
        var list2 = new ActionList();
        var desc3 = new ActionDescriptor();
        desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
        var list3 = new ActionList();
    for (var n = 0; n < thisSubPath.length - 2; n++) {
        var thisPoint = thisSubPath[n];
        var desc4 = new ActionDescriptor();
        var desc5 = new ActionDescriptor();
        desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
        desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
        desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
        var desc6 = new ActionDescriptor();
        desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
        desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
        desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
        var desc7 = new ActionDescriptor();
        desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
        desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
        desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
        desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
        list3.putObject(cTID('Pthp'), desc4);
        };
        desc3.putList(cTID('Pts '), list3);
        list2.putObject(cTID('Sbpl'), desc3);
        desc2.putList(cTID('SbpL'), list2);
        list1.putObject(cTID('PaCm'), desc2);
        };
        desc1.putList(cTID('T   '), list1);
        executeAction(cTID('setd'), desc1, DialogModes.NO);
/// get index;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("itemIndex"));
    ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
    var pathDesc = executeActionGet(ref);
    var myPathItem = activeDocument.pathItems[pathDesc.getInteger(stringIDToTypeID("itemIndex")) - 1];
    app.preferences.rulerUnits = originalRulerUnits;
    return myPathItem
    };
////// determine selected path //////
function selectedPath2020 () {
try {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex")); 
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var docDesc = executeActionGet(ref);
var theIndex = docDesc.getInteger(stringIDToTypeID("targetPathIndex"))+1;
//
var ref = new ActionReference();
ref.putIndex( charIDToTypeID("Path"), theIndex); 
var pathDesc = executeActionGet(ref);
var theKind = pathDesc.getEnumerationValue(stringIDToTypeID("kind"));
var theName = pathDesc.getString(stringIDToTypeID("pathName"));
//
return [theIndex, theKind, theName];
}
catch (e) {return undefined}
};
////// deselect layers //////
function deselectLayers() { 
var desc01 = new ActionDescriptor(); 
    var ref01 = new ActionReference(); 
    ref01.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
desc01.putReference( charIDToTypeID('null'), ref01 ); 
executeAction( stringIDToTypeID('selectNoLayers'), desc01, DialogModes.NO ); 
};

 

3 replies

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
May 26, 2020

 

// retract all bezier handles of the selected path;
// 2020, use it at your own risk;
if (app.documents.length > 0) {activeDocument.suspendHistory("reset handles", "main ()")};
////////////////////////////////////
function main () {
var thePathIndex = selectedPath2020 ();
if (thePathIndex != undefined) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var thePath = collectPathInfoFromDesc2020 (activeDocument, thePathIndex[0]);
if (thePath.length > 0) {
var originalResolution = activeDocument.resolution;
activeDocument.resizeImage (null, null, 72, ResampleMethod.NONE);
////////////////////////////////////
var theArray2 = new Array;
for (var m = 0; m < thePath.length; m++) {
var thisSubPath = thePath[m];
var thisLength = thisSubPath.length;
var aNewArray = new Array;
for (var n = 0; n < thisSubPath.length-2; n++) {
var thisPoint = thisSubPath[n];
aNewArray.push([thisPoint[0], thisPoint[0], thisPoint[0], thisPoint[3], thisPoint[4]])
};
aNewArray.push(thisSubPath[thisLength-2], thisSubPath[thisLength-1]);
theArray2.push(aNewArray)
};
////////////////////////////////////
// if the path is a vector mask;
if (thePathIndex[1] == 1953) {
var thePath = changeSelectedPath2020(theArray2);
} else {
deselectLayers();
var thePath = changeSelectedPath2020(theArray2);
};
////////////////////////////////////
// reset;
app.preferences.rulerUnits = originalRulerUnits;
activeDocument.resizeImage (null, null, originalResolution, ResampleMethod.NONE);
}
};
};
////// collect path info from actiondescriptor, smooth added //////
function collectPathInfoFromDesc2020 (myDocument, thePath) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
ref.putIndex(cTID("Path"), thePath);
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
    var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
    var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
    switch (operation1) {
        case 1097098272:
        var operation = 1097098272 //cTID('Add ');
        break;
        case 1398961266:
        var operation = 1398961266 //cTID('Sbtr');
        break;
        case 1231975538:
        var operation = 1231975538 //cTID('Intr');
        break;
        default:
//		case 1102:
        var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
        break;
        };
// for subpathitem’s count;
    for (var n = 0; n < listKey.count; n++) {
        theArray.push(new Array);
        var points = listKey.getObjectValue(n).getList(sTID('points'));
        try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
        catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
        for (var o = 0; o < points.count; o++) {
            var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
            var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
            var thisPoint = [anchor];
            try {
                var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
                var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(leftDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
                var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(rightDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
                thisPoint.push(smoothOr)
                }
            catch (e) {thisPoint.push(false)};
            theArray[theArray.length - 1].push(thisPoint);
            };
        theArray[theArray.length - 1].push(closed);
        theArray[theArray.length - 1].push(operation);
        };
    };
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// change a path based on collectPathInfoFromDesc2012-array //////
function changeSelectedPath2020(theArray) {
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
// thanks to xbytor;
    cTID = function(s) { return app.charIDToTypeID(s); };
    sTID = function(s) { return app.stringIDToTypeID(s); };
        var desc1 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putEnumerated( cTID('Path'), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
        desc1.putReference(sTID('null'), ref1);
        var list1 = new ActionList();
    for (var m = 0; m < theArray.length; m++) {
        var thisSubPath = theArray[m];
        var desc2 = new ActionDescriptor();
        desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
        var list2 = new ActionList();
        var desc3 = new ActionDescriptor();
        desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
        var list3 = new ActionList();
    for (var n = 0; n < thisSubPath.length - 2; n++) {
        var thisPoint = thisSubPath[n];
        var desc4 = new ActionDescriptor();
        var desc5 = new ActionDescriptor();
        desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
        desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
        desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
        var desc6 = new ActionDescriptor();
        desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
        desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
        desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
        var desc7 = new ActionDescriptor();
        desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
        desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
        desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
        desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
        list3.putObject(cTID('Pthp'), desc4);
        };
        desc3.putList(cTID('Pts '), list3);
        list2.putObject(cTID('Sbpl'), desc3);
        desc2.putList(cTID('SbpL'), list2);
        list1.putObject(cTID('PaCm'), desc2);
        };
        desc1.putList(cTID('T   '), list1);
        executeAction(cTID('setd'), desc1, DialogModes.NO);
/// get index;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("itemIndex"));
    ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
    var pathDesc = executeActionGet(ref);
    var myPathItem = activeDocument.pathItems[pathDesc.getInteger(stringIDToTypeID("itemIndex")) - 1];
    app.preferences.rulerUnits = originalRulerUnits;
    return myPathItem
    };
////// determine selected path //////
function selectedPath2020 () {
try {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex")); 
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var docDesc = executeActionGet(ref);
var theIndex = docDesc.getInteger(stringIDToTypeID("targetPathIndex"))+1;
//
var ref = new ActionReference();
ref.putIndex( charIDToTypeID("Path"), theIndex); 
var pathDesc = executeActionGet(ref);
var theKind = pathDesc.getEnumerationValue(stringIDToTypeID("kind"));
var theName = pathDesc.getString(stringIDToTypeID("pathName"));
//
return [theIndex, theKind, theName];
}
catch (e) {return undefined}
};
////// deselect layers //////
function deselectLayers() { 
var desc01 = new ActionDescriptor(); 
    var ref01 = new ActionReference(); 
    ref01.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
desc01.putReference( charIDToTypeID('null'), ref01 ); 
executeAction( stringIDToTypeID('selectNoLayers'), desc01, DialogModes.NO ); 
};

 

Participant
May 26, 2020

ありがとうございます!

無事動きました。とても助かりました。

Ten A
Community Expert
Community Expert
May 25, 2020

PhotoshopのJavaScriptは一般的なWebのそれとはかなり毛色の違うものであり、ECMA 3相当の骨董品でもあります。

DOMもかなり違いますから、まずはリファレンスに目を通しましょう。Photoshop JavaScript referenceはありますが、スキルレベルによっては適当な情報をググった方が早いかもしれません。

パスポイントの操作は

app.activeDocument.pathItems[0].pathPoints

の各アンカーポイントのleftDirection及びrightDirectionに対してanchorをループにて適用する処理になります。

Participant
May 25, 2020

ありがとうございます。

調べながら試してみます。

c.pfaffenbichler
Community Expert
Community Expert
May 25, 2020

Could you post screenshots with the Path visible? 

 

Resetting all the bezier handles would almost certainly need to be done via a Script. 

Do you have JavaScript experience? 

Participant
May 25, 2020

返信ありがとうございます。パスのスクリーンショットを添付します。

JavaScriptの経験はありませんが、自社内のエンジニアに相談すればわかると思います。

詳細を教えていただきたいです。