mirror of
https://github.com/sbrow/ps.git
synced 2025-12-29 18:47:38 -05:00
Improved documentation
all colors must now implement hex notation as well as rgb
This commit is contained in:
22
colors.go
22
colors.go
@@ -9,11 +9,16 @@ var Colors map[string]Color = map[string]Color{
|
|||||||
"White": &RGB{255, 255, 255},
|
"White": &RGB{255, 255, 255},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color represents a color.
|
// Color is an interface for color objects, allowing colors to be
|
||||||
|
// used in various formats.
|
||||||
|
//
|
||||||
|
// RGB is the default format for everything.
|
||||||
type Color interface {
|
type Color interface {
|
||||||
RGB() [3]int
|
RGB() [3]int // The color in RGB format.
|
||||||
|
Hex() []uint8 // The color in hexadecimal format.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare determines which of two colors is "brighter".
|
||||||
func Compare(a, b Color) Color {
|
func Compare(a, b Color) Color {
|
||||||
A := a.RGB()
|
A := a.RGB()
|
||||||
B := b.RGB()
|
B := b.RGB()
|
||||||
@@ -25,7 +30,7 @@ func Compare(a, b Color) Color {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color is a color in RGB format.
|
// RGB is a color in RGB format. It fulfills the Color interface.
|
||||||
type RGB struct {
|
type RGB struct {
|
||||||
Red int
|
Red int
|
||||||
Green int
|
Green int
|
||||||
@@ -37,7 +42,12 @@ func (r RGB) RGB() [3]int {
|
|||||||
return [3]int{r.Red, r.Green, r.Blue}
|
return [3]int{r.Red, r.Green, r.Blue}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hex is a color in hexidecimal format.
|
// TODO: Implement RGB.Hex()
|
||||||
|
func (r RGB) Hex() []uint8 {
|
||||||
|
return make([]uint8, 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex is a color in hexadecimal format. It fulfills the Color interface.
|
||||||
type Hex []uint8
|
type Hex []uint8
|
||||||
|
|
||||||
func (h Hex) RGB() [3]int {
|
func (h Hex) RGB() [3]int {
|
||||||
@@ -50,6 +60,10 @@ func (h Hex) RGB() [3]int {
|
|||||||
return [3]int{int(dst[0]), int(dst[1]), int(dst[2])}
|
return [3]int{int(dst[0]), int(dst[1]), int(dst[2])}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h Hex) Hex() []uint8 {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
// Stroke represents a layer stroke effect.
|
// Stroke represents a layer stroke effect.
|
||||||
type Stroke struct {
|
type Stroke struct {
|
||||||
Size float32
|
Size float32
|
||||||
|
|||||||
40
ps.go
40
ps.go
@@ -1,7 +1,7 @@
|
|||||||
// Package ps is a rudimentary API between Adobe Photoshop and go.
|
// Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang.
|
||||||
//
|
//
|
||||||
// Most of the interaction between the two is implemented via
|
// Most of the interaction between the two is implemented via
|
||||||
// javascript and/or VBS/Applescript.
|
// Javascript and/or VBS/Applescript.
|
||||||
//
|
//
|
||||||
// Currently only works with CS5 on Windows.
|
// Currently only works with CS5 on Windows.
|
||||||
package ps
|
package ps
|
||||||
@@ -54,30 +54,41 @@ func Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the active document.
|
// Close closes the active document in Photoshop.
|
||||||
func Close(save PSSaveOptions) error {
|
func Close(save PSSaveOptions) error {
|
||||||
_, err := run("close", save.String())
|
_, err := run("close", save.String())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens a file with the specified path.
|
// Open opens a Photoshop document with the specified path.
|
||||||
|
// If Photoshop is not currently running, it is started before
|
||||||
|
// opening the document
|
||||||
func Open(path string) error {
|
func Open(path string) error {
|
||||||
_, err := run("open", path)
|
_, err := run("open", path)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quit exits Photoshop.
|
// Quit exits Photoshop with the given saving option.
|
||||||
func Quit(save PSSaveOptions) error {
|
func Quit(save PSSaveOptions) error {
|
||||||
_, err := run("quit", save.String())
|
_, err := run("quit", save.String())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoJs runs a Photoshop javascript script file (.jsx) from the specified location.
|
// SaveAs saves the Photoshop document to the given location.
|
||||||
|
func SaveAs(path string) error {
|
||||||
|
_, err := run("save", path)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoJs runs a Photoshop Javascript script file (.jsx) from the specified location.
|
||||||
// It can't directly return output, so instead the scripts write their output to
|
// It can't directly return output, so instead the scripts write their output to
|
||||||
// a temporary file.
|
// a temporary file, whose contents is then read and returned.
|
||||||
func DoJs(path string, args ...string) (out []byte, err error) {
|
func DoJs(path string, args ...string) (out []byte, err error) {
|
||||||
// Temp file for js to output to.
|
// Temp file for js to output to.
|
||||||
outpath := filepath.Join(os.Getenv("TEMP"), "js_out.txt")
|
outpath := filepath.Join(os.Getenv("TEMP"), "js_out.txt")
|
||||||
|
if !strings.HasSuffix(path, ".jsx") {
|
||||||
|
path += ".jsx"
|
||||||
|
}
|
||||||
defer os.Remove(outpath)
|
defer os.Remove(outpath)
|
||||||
|
|
||||||
args = append([]string{outpath}, args...)
|
args = append([]string{outpath}, args...)
|
||||||
@@ -150,18 +161,12 @@ func run(name string, args ...string) ([]byte, error) {
|
|||||||
return out.Bytes(), nil
|
return out.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoAction runs a Photoshop action with name from set.
|
// DoAction runs the Photoshop action with name from set.
|
||||||
func DoAction(set, name string) error {
|
func DoAction(set, name string) error {
|
||||||
_, err := run("action", set, name)
|
_, err := run("action", set, name)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveAs saves the Photoshop document file to the given location.
|
|
||||||
func SaveAs(path string) error {
|
|
||||||
_, err := run("save", path)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Layers returns an array of ArtLayers from the active document
|
// Layers returns an array of ArtLayers from the active document
|
||||||
// based on the given path string.
|
// based on the given path string.
|
||||||
/*func Layers(path string) ([]ArtLayer, error) {
|
/*func Layers(path string) ([]ArtLayer, error) {
|
||||||
@@ -172,15 +177,16 @@ func SaveAs(path string) error {
|
|||||||
return []ArtLayer{}, err
|
return []ArtLayer{}, err
|
||||||
}
|
}
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}*/
|
||||||
*/
|
|
||||||
|
|
||||||
// ApplyDataset fills out a template file with information from a given dataset (csv) file.
|
// ApplyDataset fills out a template file with information from a given dataset (csv) file.
|
||||||
func ApplyDataset(name string) ([]byte, error) {
|
func ApplyDataset(name string) ([]byte, error) {
|
||||||
return DoJs("applyDataset.jsx", name)
|
return DoJs("applyDataset.jsx", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSLayer retrurns javascript code to get the layer with a given path.
|
// JSLayer "compiles" Javascript code to get an ArtLayer with the given path.
|
||||||
|
// The output always ends with a semicolon, so if you want to access a specific
|
||||||
|
// property of the layer, you'll have to trim the output before concatenating
|
||||||
func JSLayer(path string) string {
|
func JSLayer(path string) string {
|
||||||
path = strings.TrimLeft(path, "/")
|
path = strings.TrimLeft(path, "/")
|
||||||
pth := strings.Split(path, "/")
|
pth := strings.Split(path, "/")
|
||||||
|
|||||||
45
structs.go
45
structs.go
@@ -180,7 +180,7 @@ func (d *Document) Dump() {
|
|||||||
f.Write(byt)
|
f.Write(byt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArtLayer represents an Art Layer in a photoshop document.
|
// ArtLayer reflects certain values from an Art Layer in a Photoshop document.
|
||||||
type ArtLayer struct {
|
type ArtLayer struct {
|
||||||
name string // The layer's name.
|
name string // The layer's name.
|
||||||
// TextItem string
|
// TextItem string
|
||||||
@@ -192,6 +192,14 @@ type ArtLayer struct {
|
|||||||
*Stroke // The layer's stroke.
|
*Stroke // The layer's stroke.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bounds returns the furthest corners of the ArtLayer.
|
||||||
|
func (a *ArtLayer) Bounds() [2][2]int {
|
||||||
|
return a.bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArtLayerJSON is a bridge between the ArtLayer struct and
|
||||||
|
// the encoding/json package, allowing ArtLayer's unexported fields
|
||||||
|
// to ber written to and read from by the json package.
|
||||||
type ArtLayerJSON struct {
|
type ArtLayerJSON struct {
|
||||||
Name string
|
Name string
|
||||||
Bounds [2][2]int
|
Bounds [2][2]int
|
||||||
@@ -201,6 +209,8 @@ type ArtLayerJSON struct {
|
|||||||
StrokeAmt float32
|
StrokeAmt float32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON fufills the json.Marshaler interface, allowing the ArtLayer to be
|
||||||
|
// saved to disk in JSON format.
|
||||||
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(&ArtLayerJSON{
|
return json.Marshal(&ArtLayerJSON{
|
||||||
Name: a.name,
|
Name: a.name,
|
||||||
@@ -230,10 +240,6 @@ func (a *ArtLayer) Name() string {
|
|||||||
return a.name
|
return a.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtLayer) Bounds() [2][2]int {
|
|
||||||
return a.bounds
|
|
||||||
}
|
|
||||||
|
|
||||||
// X1 returns the layer's leftmost x value.
|
// X1 returns the layer's leftmost x value.
|
||||||
func (a *ArtLayer) X1() int {
|
func (a *ArtLayer) X1() int {
|
||||||
return a.bounds[0][0]
|
return a.bounds[0][0]
|
||||||
@@ -244,7 +250,7 @@ func (a *ArtLayer) X2() int {
|
|||||||
return a.bounds[1][0]
|
return a.bounds[1][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Y1 returns the layer's topmost Y value.
|
// Y1 returns the layer's topmost y value.
|
||||||
func (a *ArtLayer) Y1() int {
|
func (a *ArtLayer) Y1() int {
|
||||||
return a.bounds[0][1]
|
return a.bounds[0][1]
|
||||||
}
|
}
|
||||||
@@ -369,23 +375,30 @@ func (a *ArtLayer) Visible() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPos snaps the given layer boundry to the given point.
|
// SetPos snaps the given layer boundry to the given point.
|
||||||
// Valid options for bound are: TL, TR, BL, BR
|
// Valid options for bound are: "TL", "TR", "BL", "BR"
|
||||||
// TODO: Improve
|
//
|
||||||
|
// TODO: Test TR and BR
|
||||||
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
||||||
if x == 0 && y == 0 {
|
if !a.visible || (x == 0 && y == 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !a.visible {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var lyrX, lyrY int
|
var lyrX, lyrY int
|
||||||
lyrX = a.X1()
|
switch bound[:1] {
|
||||||
if bound != "TL" {
|
case "B":
|
||||||
lyrY = a.Y2()
|
lyrY = a.Y2()
|
||||||
} else { // "BL"
|
case "T":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
lyrY = a.Y1()
|
lyrY = a.Y1()
|
||||||
}
|
}
|
||||||
|
switch bound[1:] {
|
||||||
|
case "R":
|
||||||
|
lyrX = a.X2()
|
||||||
|
case "L":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
lyrX = a.X1()
|
||||||
|
}
|
||||||
byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY))
|
byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY))
|
||||||
var bounds [2][2]int
|
var bounds [2][2]int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user