Photoshop脚本 - 尺寸调整不正确

3
我已经用Javascript为Photoshop编写了一个脚本,它可以获取用户输入(桌面上方框的数量),然后将其转换为像素大小。问题在于,当调整大小时,图层的大小并不会改变到指定的大小,而是会增加指定的大小。例如,MicrosoftBox的初始大小为800*800,应该更改为500*500,但实际上会增加这个值,变成1300*1300。
app.preferences.rulerUnits = Units.PIXELS;
//Get all input
var microsoftboxes = prompt("How many boxes for microsoft?");
var gamesboxesx = prompt("How many across boxes for games?");
var gamesboxesy = prompt("How many down boxes for games?");
var adobeboxes = prompt("How many boxes for adobe?");
var filesboxes = prompt("How many boxes for files?");
var toolsboxes = prompt("How many boxes for tools?");
var recycleboxes = 1;
//Add percentage on and convert to pixel num
var mb = microsoftboxes * 75;
mb = mb + (mb * 0.04);
var gbx = gamesboxesx * 75;
gbx = gbx + (gbx * 0.04);
var gby = gamesboxesy * 75;
gby = gby + (gby * 0.04);
var ab = adobeboxes * 75;
ab = ab + (ab * 0.04);
var fb = filesboxes * 75;
fb = fb + (fb * 0.04);
var tb = toolsboxes * 75;
tb = tb + (tb * 0.04);
var rb = recycleboxes * 75;
rb = rb + (rb * 0.04);
//vars for change size
var doc = app.activeDocument;
var m = doc.layers.getByName('microsoft');
var g = doc.layers.getByName('games');
var a = doc.layers.getByName('adobe');
var t = doc.layers.getByName('tools');
var f = doc.layers.getByName('files');
var r = doc.layers.getByName('recycle');
m.resize(mb, 73, AnchorPosition.MIDDLELEFT);
g.resize(gbx, gby, AnchorPosition.TOPCENTER);
a.resize(ab, 73, AnchorPosition.MIDDLELEFT);
f.resize(fb, 73, AnchorPosition.MIDDLELEFT);
t.resize(tb, 73, AnchorPosition.MIDDLELEFT);
r.resize(rb, 73, AnchorPosition.MIDDLELEFT);

之前 之后

---更新--- 我已经确定尽管设置为像素,但是按百分比变化。例如,文件应该被设置为78,但实际上它被设置为

250 (the current value) * 0.78(78 as a percentage) = 195 

文件被设置为195像素。有什么办法可以解决这个问题吗?

现在的代码是:

var startru = app.preferences.rulerUnits;
var starttu = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
//Get all input
var microsoftboxes = prompt("How many boxes for microsoft?");
var gamesboxesx = prompt("How many across boxes for games?");
var gamesboxesy = prompt("How many down boxes for games?");
var adobeboxes = prompt("How many boxes for adobe?");
var filesboxes = prompt("How many boxes for files?");
var toolsboxes = prompt("How many boxes for tools?");
var recycleboxes = 1;
//Add percentage on and convert to pixel num
var mb = microsoftboxes * 75;
mb = mb + (mb * 0.04);
var gbx = gamesboxesx * 75;
gbx = gbx + (gbx * 0.04);
var gby = gamesboxesy * 75;
gby = gby + (gby * 0.04);
var ab = adobeboxes * 75;
ab = ab + (ab * 0.04);
var fb = filesboxes * 75;
fb = fb + (fb * 0.04);
var tb = toolsboxes * 75;
tb = tb + (tb * 0.04);
var rb = recycleboxes * 75;
rb = rb + (rb * 0.04);
//vars for change size
var doc = app.activeDocument;
var m = doc.layers.getByName('microsoft');
var g = doc.layers.getByName('games');
var a = doc.layers.getByName('adobe');
var t = doc.layers.getByName('tools');
var f = doc.layers.getByName('files');
var r = doc.layers.getByName('recycle');
m.resize(mb, 85, AnchorPosition.MIDDLELEFT);
g.resize(gbx, gby, AnchorPosition.TOPCENTER);
a.resize(ab, 85, AnchorPosition.MIDDLELEFT);
f.resize(fb, 85, AnchorPosition.MIDDLELEFT);
t.resize(tb, 85, AnchorPosition.MIDDLELEFT);
r.resize(rb, 85, AnchorPosition.MIDDLELEFT);
app.preferences.rulerUnits = startru;
app.preferences.typeUnits = starttu;

您已经设置了单位的偏好,但是请尝试在传递给 resize 的变量上明确设置单位。例如:UnitValue(10,'px')。 - Anna Forrest
抱歉,没有活跃的Photoshop开发环境,我只能从记忆中猜测:m.resize(new UnitValue(mb,'px'), new UnitValue(10,'px'), AnchorPosition.MIDDLELEFT); - Anna Forrest
谢谢。回去后我会尝试的! - KERN D
抱歉,这个程序和以前一样。也许需要放弃这个想法。但还是谢谢你花时间。 - KERN D
很遗憾,据我所知,这就是ArtLayer对象的resize方法的工作方式。根据JS脚本指南:“将图层调整为指定尺寸(作为其当前尺寸的百分比),并将其放置在指定位置。”我建议将您的图层复制到一个新文档中,使用resizeImage来达到适当的尺寸,然后再复制回原始文档。我将很快提供一个演示如何做到这一点的答案。 - InternetRebel
显示剩余8条评论
1个回答

0

如我在评论中提到的,ArtLayer对象的resize方法明确期望百分比值,并且无法接受像素值进行调整大小。我相信有一个公式可以使用当前图层的大小来确定您需要达到新特定大小的百分比,但我认为最简单的方法是:

  1. 将图层复制到新文档中
  2. 将其调整为所需的精确像素尺寸
  3. 将该图层复制回原始文档

下面是我编写的示例,以实现此目的。这不是针对您问题的复制/粘贴解决方案,而是使用您想要做的想法的说明。我认为很容易修改此代码以适应您的确切需求。

app.preferences.rulerUnits = Units.PIXELS;
var activeDoc = app.activeDocument;
//store the active document's resolution for when we create the temp doc
var res = activeDoc.resolution;

//capture the existing color mode for the temp doc
var newDocMode;
switch(activeDoc.mode) {
    case DocumentMode.RGB:
        newDocMode = NewDocumentMode.RGB;
        break;
    case DocumentMode.CMYK:
        newDocMode = NewDocumentMode.CMYK;
        break;
}

//my preference to store sizes as a JSON object
var msboxSizes = {
    sm: {
        width: 200,
        height: 200
    },
    md: {
        width: 500,
        height: 500
    }, 
    lg: {
        width: 800,
        height: 800
    }
};

//target our layer
var msboxLayer = activeDoc.artLayers.getByName("microsoftbox");

//make it the active layer
activeDoc.activeLayer = msboxLayer;

//get the bounds of the layer so we can create a new doc the same size as the image on this layer
var msboxSize = activeDoc.activeLayer.bounds;

//use the bounds to determine the width and height of the layer
var msboxWidth = (msboxSize[2].value - msboxSize[0].value).toFixed(0);
var msboxHeight = (msboxSize[3].value - msboxSize[1].value).toFixed(0);

//convert those values back into pixels
msboxWidth = new UnitValue(msboxWidth, "px");
msboxHeight = new UnitValue(msboxHeight, "px");

//copy our layer to the clipboard
msboxLayer.copy();

//create a new doc that is the same size, resolution and color mode as the layer we want to resize
var tempDoc = app.documents.add(msboxWidth, msboxHeight, res, "Temp Doc", newDocMode, DocumentFill.TRANSPARENT);

//set the temp doc as the active document
app.activeDocument = tempDoc;
//paste the layer into the temp doc
tempDoc.paste();

//store the different size obj keys in an array (could use array of objects and skip this bit)
var resizes = ["lg","md","sm"]
//loop through resizing to each size in the array, copy and paste them as layers into the original document
for (i = 0; i < resizes.length; i++) {
    var newWidth = msboxSizes[resizes[i]].width;
    var newHeight = msboxSizes[resizes[i]].height;

    app.activeDocument = tempDoc;
    tempDoc.resizeImage(newWidth, newHeight, res, ResampleMethod.BICUBIC);
    tempDoc.activeLayer.copy();

    app.activeDocument = activeDoc;
    activeDoc.paste();
}

//close the temp doc and dont save it
tempDoc.close(SaveOptions.DONOTSAVECHANGES);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接