mirror of
https://github.com/sbrow/ps.git
synced 2025-12-29 18:47:38 -05:00
Can now color layers and apply strokes
This commit is contained in:
1
ps.go
1
ps.go
@@ -11,6 +11,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
// "log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
26
ps_test.go
26
ps_test.go
@@ -159,8 +159,29 @@ func TestActiveDocument(t *testing.T) {
|
||||
fmt.Println(d.layerSets[0].artLayers[0].Parent())
|
||||
t.Fatal("Layerset's ArtLayers do not have correct parents")
|
||||
}
|
||||
// d.LayerSet("Areas").LayerSet("Bottom").ArtLayer("L Bar").SetColor(155, 255, 255)
|
||||
lyr := d.LayerSet("Text").ArtLayer("speed")
|
||||
if lyr == nil {
|
||||
t.Fatal("lyr does not exist")
|
||||
}
|
||||
s := Stroke{Size: 4, Color: &RGB{0, 0, 0}}
|
||||
lyr.SetStroke(s, &RGB{128, 128, 128})
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
func TestColor(t *testing.T) {
|
||||
byt, err := run("colorLayer.vbs", "255", "255", "255")
|
||||
fmt.Println(string(byt))
|
||||
fmt.Println(err)
|
||||
if err != nil {
|
||||
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
func TestApplyDataset(t *testing.T) {
|
||||
out := []byte("done!\r\n")
|
||||
ret, err := ApplyDataset(" Anger")
|
||||
@@ -174,6 +195,9 @@ func TestApplyDataset(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDocumentLayerSet(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping TestDocumentLayerSet")
|
||||
}
|
||||
d, err := ActiveDocument()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -191,7 +215,7 @@ func TestDocumentLayerSet(t *testing.T) {
|
||||
fmt.Println(lyr.name)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
func TestDoJs_HideLayer(t *testing.T) {
|
||||
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
|
||||
|
||||
76
scripts/colorLayer.vbs
Normal file
76
scripts/colorLayer.vbs
Normal file
@@ -0,0 +1,76 @@
|
||||
DIM objApp
|
||||
SET objApp = CreateObject("Photoshop.Application")
|
||||
DIM dialogMode
|
||||
dialogMode = 3
|
||||
DIM idsetd
|
||||
idsetd = objApp.CharIDToTypeID("setd")
|
||||
DIM desc134
|
||||
SET desc134 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idnull
|
||||
idnull = objApp.CharIDToTypeID("null")
|
||||
DIM ref44
|
||||
SET ref44 = CreateObject("Photoshop.ActionReference")
|
||||
DIM idPrpr
|
||||
idPrpr = objApp.CharIDToTypeID("Prpr")
|
||||
DIM idLefx
|
||||
idLefx = objApp.CharIDToTypeID("Lefx")
|
||||
Call ref44.PutProperty(idPrpr, idLefx)
|
||||
DIM idLyr
|
||||
idLyr = objApp.CharIDToTypeID("Lyr ")
|
||||
DIM idOrdn
|
||||
idOrdn = objApp.CharIDToTypeID("Ordn")
|
||||
DIM idTrgt
|
||||
idTrgt = objApp.CharIDToTypeID("Trgt")
|
||||
Call ref44.PutEnumerated(idLyr, idOrdn, idTrgt)
|
||||
Call desc134.PutReference(idnull, ref44)
|
||||
DIM idT
|
||||
idT = objApp.CharIDToTypeID("T ")
|
||||
DIM desc135
|
||||
SET desc135 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idScl
|
||||
idScl = objApp.CharIDToTypeID("Scl ")
|
||||
DIM idPrc
|
||||
idPrc = objApp.CharIDToTypeID("#Prc")
|
||||
Call desc135.PutUnitDouble(idScl, idPrc, 416.666667)
|
||||
DIM idSoFi
|
||||
idSoFi = objApp.CharIDToTypeID("SoFi")
|
||||
DIM desc136
|
||||
SET desc136 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idenab
|
||||
idenab = objApp.CharIDToTypeID("enab")
|
||||
Call desc136.PutBoolean(idenab, True)
|
||||
DIM idMd
|
||||
idMd = objApp.CharIDToTypeID("Md ")
|
||||
DIM idBlnM
|
||||
idBlnM = objApp.CharIDToTypeID("BlnM")
|
||||
DIM idNrml
|
||||
idNrml = objApp.CharIDToTypeID("Nrml")
|
||||
Call desc136.PutEnumerated(idMd, idBlnM, idNrml)
|
||||
DIM idOpct
|
||||
idOpct = objApp.CharIDToTypeID("Opct")
|
||||
idPrc = objApp.CharIDToTypeID("#Prc")
|
||||
Call desc136.PutUnitDouble(idOpct, idPrc, 100.000000)
|
||||
DIM idClr
|
||||
idClr = objApp.CharIDToTypeID("Clr ")
|
||||
DIM desc137
|
||||
SET desc137 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idRd
|
||||
idRd = objApp.CharIDToTypeID("Rd ")
|
||||
Call desc137.PutDouble(idRd, CInt(wScript.Arguments(0)))
|
||||
' Call desc137.PutDouble(idRd, 255)
|
||||
DIM idGrn
|
||||
idGrn = objApp.CharIDToTypeID("Grn ")
|
||||
Call desc137.PutDouble(idGrn, Cint(wScript.Arguments(1)))
|
||||
' Call desc137.PutDouble(idGrn, 255)
|
||||
DIM idBl
|
||||
idBl = objApp.CharIDToTypeID("Bl ")
|
||||
Call desc137.PutDouble(idBl, CInt(wScript.Arguments(2)))
|
||||
' Call desc137.PutDouble(idBl, 255)
|
||||
DIM idRGBC
|
||||
idRGBC = objApp.CharIDToTypeID("RGBC")
|
||||
Call desc136.PutObject(idClr, idRGBC, desc137)
|
||||
idSoFi = objApp.CharIDToTypeID("SoFi")
|
||||
Call desc135.PutObject(idSoFi, idSoFi, desc136)
|
||||
idLefx = objApp.CharIDToTypeID("Lefx")
|
||||
Call desc134.PutObject(idT, idLefx, desc135)
|
||||
Call objApp.ExecuteAction(idsetd, desc134, dialogMode)
|
||||
120
scripts/colorStroke.vbs
Normal file
120
scripts/colorStroke.vbs
Normal file
@@ -0,0 +1,120 @@
|
||||
DIM objApp
|
||||
SET objApp = CreateObject("Photoshop.Application")
|
||||
REM Use dialog mode 3 for show no dialogs
|
||||
DIM dialogMode
|
||||
dialogMode = 3
|
||||
DIM idsetd
|
||||
idsetd = objApp.CharIDToTypeID("setd")
|
||||
DIM desc2
|
||||
SET desc2 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idnull
|
||||
idnull = objApp.CharIDToTypeID("null")
|
||||
DIM ref2
|
||||
SET ref2 = CreateObject("Photoshop.ActionReference")
|
||||
DIM idPrpr
|
||||
idPrpr = objApp.CharIDToTypeID("Prpr")
|
||||
DIM idLefx
|
||||
idLefx = objApp.CharIDToTypeID("Lefx")
|
||||
Call ref2.PutProperty(idPrpr, idLefx)
|
||||
DIM idLyr
|
||||
idLyr = objApp.CharIDToTypeID("Lyr ")
|
||||
DIM idOrdn
|
||||
idOrdn = objApp.CharIDToTypeID("Ordn")
|
||||
DIM idTrgt
|
||||
idTrgt = objApp.CharIDToTypeID("Trgt")
|
||||
Call ref2.PutEnumerated(idLyr, idOrdn, idTrgt)
|
||||
Call desc2.PutReference(idnull, ref2)
|
||||
DIM idT
|
||||
idT = objApp.CharIDToTypeID("T ")
|
||||
DIM desc3
|
||||
SET desc3 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idScl
|
||||
idScl = objApp.CharIDToTypeID("Scl ")
|
||||
DIM idPrc
|
||||
idPrc = objApp.CharIDToTypeID("#Prc")
|
||||
Call desc3.PutUnitDouble(idScl, idPrc, 416.666667)
|
||||
DIM idSoFi
|
||||
idSoFi = objApp.CharIDToTypeID("SoFi")
|
||||
DIM desc4
|
||||
SET desc4 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idenab
|
||||
idenab = objApp.CharIDToTypeID("enab")
|
||||
Call desc4.PutBoolean(idenab, True)
|
||||
DIM idMd
|
||||
idMd = objApp.CharIDToTypeID("Md ")
|
||||
DIM idBlnM
|
||||
idBlnM = objApp.CharIDToTypeID("BlnM")
|
||||
DIM idNrml
|
||||
idNrml = objApp.CharIDToTypeID("Nrml")
|
||||
Call desc4.PutEnumerated(idMd, idBlnM, idNrml)
|
||||
DIM idOpct
|
||||
idOpct = objApp.CharIDToTypeID("Opct")
|
||||
idPrc = objApp.CharIDToTypeID("#Prc")
|
||||
Call desc4.PutUnitDouble(idOpct, idPrc, 100.000000)
|
||||
DIM idClr
|
||||
idClr = objApp.CharIDToTypeID("Clr ")
|
||||
DIM desc5
|
||||
SET desc5 = CreateObject("Photoshop.ActionDescriptor")
|
||||
DIM idRd
|
||||
idRd = objApp.CharIDToTypeID("Rd ")
|
||||
Call desc5.PutDouble(idRd, CInt(wScript.Arguments(0)))
|
||||
DIM idGrn
|
||||
idGrn = objApp.CharIDToTypeID("Grn ")
|
||||
Call desc5.PutDouble(idGrn,CInt(wScript.Arguments(1)))
|
||||
DIM idBl
|
||||
idBl = objApp.CharIDToTypeID("Bl ")
|
||||
Call desc5.PutDouble(idBl, CInt(wScript.Arguments(2)))
|
||||
DIM idRGBC
|
||||
idRGBC = objApp.CharIDToTypeID("RGBC")
|
||||
Call desc4.PutObject(idClr, idRGBC, desc5)
|
||||
idSoFi = objApp.CharIDToTypeID("SoFi")
|
||||
Call desc3.PutObject(idSoFi, idSoFi, desc4)
|
||||
DIM idFrFX
|
||||
idFrFX = objApp.CharIDToTypeID("FrFX")
|
||||
DIM desc6
|
||||
SET desc6 = CreateObject("Photoshop.ActionDescriptor")
|
||||
idenab = objApp.CharIDToTypeID("enab")
|
||||
Call desc6.PutBoolean(idenab, True)
|
||||
DIM idStyl
|
||||
idStyl = objApp.CharIDToTypeID("Styl")
|
||||
DIM idFStl
|
||||
idFStl = objApp.CharIDToTypeID("FStl")
|
||||
DIM idOutF
|
||||
idOutF = objApp.CharIDToTypeID("OutF")
|
||||
Call desc6.PutEnumerated(idStyl, idFStl, idOutF)
|
||||
DIM idPntT
|
||||
idPntT = objApp.CharIDToTypeID("PntT")
|
||||
DIM idFrFl
|
||||
idFrFl = objApp.CharIDToTypeID("FrFl")
|
||||
DIM idSClr
|
||||
idSClr = objApp.CharIDToTypeID("SClr")
|
||||
Call desc6.PutEnumerated(idPntT, idFrFl, idSClr)
|
||||
idMd = objApp.CharIDToTypeID("Md ")
|
||||
idBlnM = objApp.CharIDToTypeID("BlnM")
|
||||
idNrml = objApp.CharIDToTypeID("Nrml")
|
||||
Call desc6.PutEnumerated(idMd, idBlnM, idNrml)
|
||||
idOpct = objApp.CharIDToTypeID("Opct")
|
||||
idPrc = objApp.CharIDToTypeID("#Prc")
|
||||
Call desc6.PutUnitDouble(idOpct, idPrc, 100.000000)
|
||||
DIM idSz
|
||||
idSz = objApp.CharIDToTypeID("Sz ")
|
||||
DIM idPxl
|
||||
idPxl = objApp.CharIDToTypeID("#Pxl")
|
||||
Call desc6.PutUnitDouble(idSz, idPxl, CLng(wScript.Arguments(3)))
|
||||
idClr = objApp.CharIDToTypeID("Clr ")
|
||||
DIM desc7
|
||||
SET desc7 = CreateObject("Photoshop.ActionDescriptor")
|
||||
idRd = objApp.CharIDToTypeID("Rd ")
|
||||
Call desc7.PutDouble(idRd, CInt(wScript.Arguments(4)))
|
||||
idGrn = objApp.CharIDToTypeID("Grn ")
|
||||
Call desc7.PutDouble(idGrn, CInt(wScript.Arguments(5)))
|
||||
idBl = objApp.CharIDToTypeID("Bl ")
|
||||
Call desc7.PutDouble(idBl, CInt(wScript.Arguments(6)))
|
||||
idRGBC = objApp.CharIDToTypeID("RGBC")
|
||||
Call desc6.PutObject(idClr, idRGBC, desc7)
|
||||
idFrFX = objApp.CharIDToTypeID("FrFX")
|
||||
Call desc3.PutObject(idFrFX, idFrFX, desc6)
|
||||
idLefx = objApp.CharIDToTypeID("Lefx")
|
||||
Call desc2.PutObject(idT, idLefx, desc3)
|
||||
Call objApp.ExecuteAction(idsetd, desc2, dialogMode)
|
||||
|
||||
@@ -8,20 +8,6 @@ function newFile(path) {
|
||||
return f
|
||||
}
|
||||
|
||||
// Moves a layer
|
||||
function positionLayer(lyr, x, y, alignment){
|
||||
if(lyr.iisBackgroundLayer||lyr.positionLocked) return
|
||||
var layerBounds = lyr.bounds;
|
||||
var layerX = layerBounds[0].value;
|
||||
if (alignment == 'top' || alignment == null)
|
||||
var layerY = layerBounds[1].value;
|
||||
else if (alignment == 'bottom')
|
||||
var layerY = layerBounds[3].value;
|
||||
var deltaX = x-layerX;
|
||||
var deltaY = y-layerY;
|
||||
lyr.translate(deltaX, deltaY);
|
||||
}
|
||||
|
||||
// Prints an error message.
|
||||
function err(e) {
|
||||
return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line;
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
function setTitle(title) {
|
||||
var nameLayer = this.textLayers.getByName('name');
|
||||
var found = false;
|
||||
for (var i = 0; i < this.titleBackgrounds.length; i++) {
|
||||
if (!found && (nameLayer.bounds[2] + this.tolerance.title) < this.titleBackgrounds[i].bounds[2]) {
|
||||
this.log.log('"{0}" is long enough'.format(this.titleBackgrounds[i].name), '-');
|
||||
this.titleBackgrounds[i].visible = true;
|
||||
found = true;
|
||||
} else {
|
||||
this.log.log('"{0}" is too short'.format(this.titleBackgrounds[i].name),'-')
|
||||
this.titleBackgrounds[i].visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function main() {
|
||||
setTitle()
|
||||
if ((this.Type).indexOf("Channel") != -2) {
|
||||
this.changeColor(this.resolveBanner.normal, this.colors.Rarity);
|
||||
} else {
|
||||
this.changeColor(this.resolveBanner.normal, [128, 128, 128]);
|
||||
}
|
||||
formatText()
|
||||
}
|
||||
|
||||
function formatText() {
|
||||
|
||||
var lyrs = getLayers(arguments[1])
|
||||
|
||||
var speed = lyrs.getByName('speed');
|
||||
if (speed.visible) {
|
||||
this.changeStroke(speed, (speed.textItem.contents == 1) ? [128, 128, 128] : [255, 255, 255],
|
||||
this.colors.banner)
|
||||
}
|
||||
var bottom = this.doc.height-this.tolerance.flavor_text
|
||||
|
||||
// var short_text = this.setTextLayer('short_text', undefined, null, 'Arial', 'Regular',[this.bold_words, "Bold"]);
|
||||
var short_text = lyrs.getByName('short_text')
|
||||
var long_text = lyrs.getByName('long_text');
|
||||
var flavor_text = lyrs.getByName('flavor_text');
|
||||
|
||||
positionLayer(this.short_textBackground, this.short_textBackground.bounds[0], short_text.bounds[3] + this.tolerance.short_text, 'bottom');
|
||||
positionLayer(long_text, long_text.bounds[0], this.short_textBackground.bounds[3] + this.tolerance.long_text, 'top');
|
||||
positionLayer(flavor_text, flavor_text.bounds[0], bottom, 'bottom');
|
||||
|
||||
short_text.visible = short_text.textItem.contents != "“";
|
||||
long_text.visible = long_text.textItem.contents != "“";
|
||||
flavor_text.visible = flavor_text.textItem.contents != "“";
|
||||
|
||||
if (long_text.bounds[3] > this.doc.height - bottom) {
|
||||
long_text.visible == false;
|
||||
}
|
||||
|
||||
if ( (long_text.visible && flavor_text.bounds[1] < long_text.bounds[3])
|
||||
|| (short_text.visible && flavor_text.bounds[1] < short_text.bounds[3])) {
|
||||
flavor_text.visible = false;
|
||||
}
|
||||
};
|
||||
109
structs.go
109
structs.go
@@ -1,6 +1,7 @@
|
||||
package ps
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -8,6 +9,53 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Color represents a color.
|
||||
type Color interface {
|
||||
RGB() [3]int
|
||||
}
|
||||
|
||||
func Compare(a, b Color) Color {
|
||||
A := a.RGB()
|
||||
B := b.RGB()
|
||||
Aavg := (A[0] + A[1] + A[2]) / 3
|
||||
Bavg := (B[0] + B[1] + B[2]) / 3
|
||||
if Aavg > Bavg {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Color is a color in RGB format.
|
||||
type RGB struct {
|
||||
Red int
|
||||
Green int
|
||||
Blue int
|
||||
}
|
||||
|
||||
// RGB returns the color in RGB format.
|
||||
func (r *RGB) RGB() [3]int {
|
||||
return [3]int{r.Red, r.Green, r.Blue}
|
||||
}
|
||||
|
||||
// Hex is a color in hexidecimal format.
|
||||
type Hex []uint8
|
||||
|
||||
func (h Hex) RGB() [3]int {
|
||||
src := []byte(h)
|
||||
dst := make([]byte, hex.DecodedLen(len(src)))
|
||||
_, err := hex.Decode(dst, src)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return [3]int{int(dst[0]), int(dst[1]), int(dst[2])}
|
||||
}
|
||||
|
||||
// Stroke represents a layer stroke effect.
|
||||
type Stroke struct {
|
||||
Size float32
|
||||
Color
|
||||
}
|
||||
|
||||
// Group represents a Document or LayerSet.
|
||||
type Group interface {
|
||||
Name() string
|
||||
@@ -114,6 +162,8 @@ type ArtLayer struct {
|
||||
bounds [2][2]int
|
||||
parent Group
|
||||
visible bool
|
||||
Color
|
||||
*Stroke
|
||||
}
|
||||
|
||||
type ArtLayerJSON struct {
|
||||
@@ -167,6 +217,61 @@ func (a *ArtLayer) SetParent(c Group) {
|
||||
a.parent = c
|
||||
}
|
||||
|
||||
// SetActive makes this layer active in photoshop.
|
||||
// Layers need to be active to perform certain operations
|
||||
func (a *ArtLayer) SetActive() ([]byte, error) {
|
||||
js := fmt.Sprintf("app.activeDocument.activeLayer=%s", JSLayer(a.Path()))
|
||||
return DoJs("compilejs.jsx", js)
|
||||
}
|
||||
|
||||
// SetColor creates a color overlay for the layer
|
||||
func (a *ArtLayer) SetColor(c Color) {
|
||||
a.Color = c
|
||||
cols := c.RGB()
|
||||
r := cols[0]
|
||||
g := cols[1]
|
||||
b := cols[2]
|
||||
if a.Stroke != nil {
|
||||
a.SetStroke(Stroke{a.Stroke.Size, a.Stroke.Color}, a.Color)
|
||||
return
|
||||
}
|
||||
byt, err := a.SetActive()
|
||||
if len(byt) != 0 {
|
||||
log.Println(string(byt), "err")
|
||||
}
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
byt, err = run("colorLayer", fmt.Sprint(r), fmt.Sprint(g), fmt.Sprint(b))
|
||||
if len(byt) != 0 {
|
||||
log.Println(string(byt), "err")
|
||||
}
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArtLayer) SetStroke(stk Stroke, fill Color) {
|
||||
byt, err := a.SetActive()
|
||||
if len(byt) != 0 {
|
||||
log.Println(string(byt))
|
||||
}
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
stkCol := stk.Color.RGB()
|
||||
col := fill.RGB()
|
||||
byt, err = run("colorStroke", fmt.Sprint(col[0]), fmt.Sprint(col[1]), fmt.Sprint(col[2]),
|
||||
fmt.Sprintf("%.2f", stk.Size), fmt.Sprint(stkCol[0]), fmt.Sprint(stkCol[1]), fmt.Sprint(stkCol[2]))
|
||||
if len(byt) != 0 {
|
||||
log.Println(string(byt))
|
||||
}
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (a *ArtLayer) Parent() Group {
|
||||
return a.parent
|
||||
}
|
||||
@@ -204,6 +309,10 @@ func (a *ArtLayer) Visible() bool {
|
||||
// Valid options for bound are: TL, TR, BL, BR
|
||||
// TODO: Improve
|
||||
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
||||
if !a.visible {
|
||||
return
|
||||
}
|
||||
|
||||
var lyrX, lyrY int
|
||||
lyrX = a.X1()
|
||||
if bound != "TL" {
|
||||
|
||||
Reference in New Issue
Block a user