Can now color layers and apply strokes

This commit is contained in:
Unknown
2018-03-20 19:15:23 -04:00
parent 8f0e80863c
commit 71219e64d9
7 changed files with 331 additions and 74 deletions

1
ps.go
View File

@@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
// "log"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"

View File

@@ -159,8 +159,29 @@ func TestActiveDocument(t *testing.T) {
fmt.Println(d.layerSets[0].artLayers[0].Parent()) fmt.Println(d.layerSets[0].artLayers[0].Parent())
t.Fatal("Layerset's ArtLayers do not have correct parents") 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) { func TestApplyDataset(t *testing.T) {
out := []byte("done!\r\n") out := []byte("done!\r\n")
ret, err := ApplyDataset(" Anger") ret, err := ApplyDataset(" Anger")
@@ -174,6 +195,9 @@ func TestApplyDataset(t *testing.T) {
} }
func TestDocumentLayerSet(t *testing.T) { func TestDocumentLayerSet(t *testing.T) {
if testing.Short() {
t.Skip("Skipping TestDocumentLayerSet")
}
d, err := ActiveDocument() d, err := ActiveDocument()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -191,7 +215,7 @@ func TestDocumentLayerSet(t *testing.T) {
fmt.Println(lyr.name) fmt.Println(lyr.name)
} }
} }
*/
/* /*
func TestDoJs_HideLayer(t *testing.T) { func TestDoJs_HideLayer(t *testing.T) {
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd") err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")

76
scripts/colorLayer.vbs Normal file
View 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
View 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)

View File

@@ -8,20 +8,6 @@ function newFile(path) {
return f 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. // Prints an error message.
function err(e) { function err(e) {
return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line; return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line;

View File

@@ -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;
}
};

View File

@@ -1,6 +1,7 @@
package ps package ps
import ( import (
"encoding/hex"
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
@@ -8,6 +9,53 @@ import (
"strings" "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. // Group represents a Document or LayerSet.
type Group interface { type Group interface {
Name() string Name() string
@@ -114,6 +162,8 @@ type ArtLayer struct {
bounds [2][2]int bounds [2][2]int
parent Group parent Group
visible bool visible bool
Color
*Stroke
} }
type ArtLayerJSON struct { type ArtLayerJSON struct {
@@ -167,6 +217,61 @@ func (a *ArtLayer) SetParent(c Group) {
a.parent = c 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 { func (a *ArtLayer) Parent() Group {
return a.parent return a.parent
} }
@@ -204,6 +309,10 @@ func (a *ArtLayer) Visible() bool {
// Valid options for bound are: TL, TR, BL, BR // Valid options for bound are: TL, TR, BL, BR
// TODO: Improve // TODO: Improve
func (a *ArtLayer) SetPos(x, y int, bound string) { func (a *ArtLayer) SetPos(x, y int, bound string) {
if !a.visible {
return
}
var lyrX, lyrY int var lyrX, lyrY int
lyrX = a.X1() lyrX = a.X1()
if bound != "TL" { if bound != "TL" {