From 71219e64d9564454b047803b3a8e29bd5ec830b1 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 20 Mar 2018 19:15:23 -0400 Subject: [PATCH] Can now color layers and apply strokes --- ps.go | 1 + ps_test.go | 26 ++++++++- scripts/colorLayer.vbs | 76 +++++++++++++++++++++++++ scripts/colorStroke.vbs | 120 ++++++++++++++++++++++++++++++++++++++++ scripts/lib.js | 14 ----- scripts/skirmish.jsx | 59 -------------------- structs.go | 109 ++++++++++++++++++++++++++++++++++++ 7 files changed, 331 insertions(+), 74 deletions(-) create mode 100644 scripts/colorLayer.vbs create mode 100644 scripts/colorStroke.vbs delete mode 100644 scripts/skirmish.jsx diff --git a/ps.go b/ps.go index 97dd44f..dc30302 100644 --- a/ps.go +++ b/ps.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "io/ioutil" + // "log" "os" "os/exec" "path/filepath" diff --git a/ps_test.go b/ps_test.go index f5c579a..53910a1 100644 --- a/ps_test.go +++ b/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") diff --git a/scripts/colorLayer.vbs b/scripts/colorLayer.vbs new file mode 100644 index 0000000..cd5dc29 --- /dev/null +++ b/scripts/colorLayer.vbs @@ -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) \ No newline at end of file diff --git a/scripts/colorStroke.vbs b/scripts/colorStroke.vbs new file mode 100644 index 0000000..b2b1f92 --- /dev/null +++ b/scripts/colorStroke.vbs @@ -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) + diff --git a/scripts/lib.js b/scripts/lib.js index 7046b59..70a5983 100644 --- a/scripts/lib.js +++ b/scripts/lib.js @@ -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; diff --git a/scripts/skirmish.jsx b/scripts/skirmish.jsx deleted file mode 100644 index 09f88ea..0000000 --- a/scripts/skirmish.jsx +++ /dev/null @@ -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; - } -}; \ No newline at end of file diff --git a/structs.go b/structs.go index 94e20e2..ecfa770 100644 --- a/structs.go +++ b/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" {