psd 3.1.2 → 3.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +29 -21
- data/lib/psd.rb +1 -0
- data/lib/psd/file.rb +4 -1
- data/lib/psd/image.rb +1 -1
- data/lib/psd/layer_info/typetool.rb +1 -9
- data/lib/psd/layer_mask.rb +1 -2
- data/lib/psd/resources/xmp_metadata.rb +46 -0
- data/lib/psd/version.rb +1 -1
- data/psd.gemspec +2 -1
- metadata +19 -5
- data/circle.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f50b617c54533215a7298c60bd67cf41a822b9b4
|
4
|
+
data.tar.gz: 5e460352673f2a562d1539ef354297a776431beb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48fb4c174e1faace5c98f63f5a5ed584a4a459c553d7c284efa1e15b22bfdbc5e28bfd93dac16d4e9a1f7c47dba1dc3f40e05d9c514e1045ccd90590d38f39d3
|
7
|
+
data.tar.gz: 79ebfea952eb57031c6cc0d57e803728c20cb107597a2df578261dcf677708d5a998701039ef9a4032aad374a556ce33a2dc816dbf64ab17c9ec5756cfa96f70
|
data/README.md
CHANGED
@@ -19,9 +19,8 @@ A general purpose Photoshop file parser written in Ruby. It allows you to work w
|
|
19
19
|
|
20
20
|
PSD.rb is tested against:
|
21
21
|
|
22
|
-
* MRI 1.9.3
|
22
|
+
* MRI 1.9.3, 2.0.0, 2.1.0
|
23
23
|
* JRuby (1.9.3 mode)
|
24
|
-
* Rubinius (1.9.3 mode)
|
25
24
|
|
26
25
|
If you use MRI Ruby and are interested in significantly speeding up PSD.rb with native code, check out [psd_native](https://github.com/layervault/psd_native).
|
27
26
|
|
@@ -76,15 +75,23 @@ end
|
|
76
75
|
|
77
76
|
### Traversing the Document
|
78
77
|
|
79
|
-
To access the document as a tree structure, use `psd.tree` to get the root node. From there,
|
78
|
+
To access the document as a tree structure, use `psd.tree` to get the root node. From there, work with the tree using any of these methods:
|
80
79
|
|
81
80
|
* `root`: get the root node from anywhere in the tree
|
81
|
+
* `root?`: is this the root node?
|
82
82
|
* `children`: get all immediate children of the node
|
83
|
+
* `has_children?`: does this node have any children?
|
84
|
+
* `childless?`: opposite of `has_children?`
|
83
85
|
* `ancestors`: get all ancestors in the path of this node (excluding the root)
|
84
86
|
* `siblings`: get all sibling tree nodes including the current one (e.g. all layers in a folder)
|
87
|
+
* `next_sibling`: gets the sibling immediately following the current node
|
88
|
+
* `prev_sibling`: gets the sibling immediately before the current node
|
89
|
+
* `has_siblings?`: does this node have any siblings?
|
90
|
+
* `only_child?`: opposite of `has_siblings?`
|
85
91
|
* `descendants`: get all descendant nodes not including the current one
|
86
92
|
* `subtree`: same as descendants but starts with the current node
|
87
|
-
* `depth`: calculate the depth of the current node
|
93
|
+
* `depth`: calculate the depth of the current node (root node is 0)
|
94
|
+
* `path`: gets the path to the current node
|
88
95
|
|
89
96
|
For any of the traversal methods, you can also retrieve folder or layer nodes only by appending `_layers` or `_groups` to the method. For example:
|
90
97
|
|
@@ -96,6 +103,7 @@ If you know the path to a group or layer within the tree, you can search by that
|
|
96
103
|
|
97
104
|
``` ruby
|
98
105
|
psd.tree.children_at_path("Version A/Matte")
|
106
|
+
psd.tree.children_at_path(["Version A", "Matte"])
|
99
107
|
```
|
100
108
|
|
101
109
|
### Layer Comps
|
@@ -111,7 +119,7 @@ tree = psd.tree.filter_by_comp('Version A')
|
|
111
119
|
puts tree.children.map(&:name)
|
112
120
|
```
|
113
121
|
|
114
|
-
This returns a new node tree and does not alter the original
|
122
|
+
This returns a new node tree and does not alter the original.
|
115
123
|
|
116
124
|
### Accessing Layer Data
|
117
125
|
|
@@ -197,6 +205,20 @@ png = psd.image.to_png # reference to PNG data
|
|
197
205
|
psd.image.save_as_png 'path/to/output.png' # writes PNG to disk
|
198
206
|
```
|
199
207
|
|
208
|
+
This uses the full rasterized preview provided by Photoshop. It does not use the built-in rendering engine (described below). If the file was not saved with Compatibility Mode enabled, this will return an empty image.
|
209
|
+
|
210
|
+
### Preview Building
|
211
|
+
|
212
|
+
You can build previews of any subset or version of the PSD document using the built-in renderer. This is useful for generating previews of layer comps or exporting individual layer groups as images.
|
213
|
+
|
214
|
+
``` ruby
|
215
|
+
# Save a layer comp
|
216
|
+
psd.tree.filter_by_comp("Version A").save_as_png('./Version A.png')
|
217
|
+
|
218
|
+
# Generate PNG of individual layer group
|
219
|
+
psd.tree.children_at_path("Group 1").first.to_png
|
220
|
+
```
|
221
|
+
|
200
222
|
### Debugging
|
201
223
|
|
202
224
|
If you run into any problems parsing a PSD, you can enable debug logging via the `PSD_DEBUG` environment variable. For example:
|
@@ -205,31 +227,17 @@ If you run into any problems parsing a PSD, you can enable debug logging via the
|
|
205
227
|
PSD_DEBUG=true bundle exec examples/parse.rb
|
206
228
|
```
|
207
229
|
|
208
|
-
|
230
|
+
If you need to enable debugging programatically:
|
209
231
|
|
210
232
|
``` ruby
|
211
233
|
PSD.debug = true
|
212
234
|
```
|
213
235
|
|
214
|
-
### Preview Building
|
215
|
-
|
216
|
-
**This is currently an experimental feature. It works "well enough" but is not perfect yet.**
|
217
|
-
|
218
|
-
You can build previews of any subset or version of the PSD document. This is useful for generating previews of layer comps or exporting individual layer groups as images.
|
219
|
-
|
220
|
-
``` ruby
|
221
|
-
# Save a layer comp
|
222
|
-
psd.tree.filter_by_comp("Version A").save_as_png('./Version A.png')
|
223
|
-
|
224
|
-
# Generate PNG of individual layer group
|
225
|
-
psd.tree.children_at_path("Group 1").first.to_png
|
226
|
-
```
|
227
|
-
|
228
236
|
## To-do
|
229
237
|
|
230
238
|
There are a few features that are currently missing from PSD.rb.
|
231
239
|
|
232
240
|
* More image modes + depths for image exporting
|
233
|
-
* A few layer info blocks
|
234
241
|
* Support for rendering all layer styles
|
242
|
+
* Support for layer comp adjusted layer styles
|
235
243
|
* Render engine fixes for groups with lowered opacity
|
data/lib/psd.rb
CHANGED
data/lib/psd/file.rb
CHANGED
@@ -82,7 +82,10 @@ class PSD
|
|
82
82
|
# Reads a unicode string, which is double the length of a normal string and encoded as UTF-16.
|
83
83
|
def read_unicode_string(length=nil)
|
84
84
|
length ||= read_int if length.nil?
|
85
|
-
|
85
|
+
return '' if length.nil? || length <= 0
|
86
|
+
read(length * 2)
|
87
|
+
.encode('UTF-8', 'UTF-16BE', universal_newline: true)
|
88
|
+
.delete("\000")
|
86
89
|
end
|
87
90
|
|
88
91
|
# Reads a boolean value.
|
data/lib/psd/image.rb
CHANGED
@@ -18,9 +18,6 @@ class PSD
|
|
18
18
|
descriptor_version = @file.read_int
|
19
19
|
|
20
20
|
@data[:text] = Descriptor.new(@file).parse
|
21
|
-
@data[:text]['EngineData']
|
22
|
-
.encode!('UTF-8', 'MacRoman', invalid: :replace, undef: :replace)
|
23
|
-
.delete!("\000")
|
24
21
|
|
25
22
|
@data[:engine_data] = nil
|
26
23
|
begin
|
@@ -44,12 +41,7 @@ class PSD
|
|
44
41
|
# Extracts the text within the text area. In the event that psd-enginedata fails
|
45
42
|
# for some reason, we attempt to extract the text using some rough regex.
|
46
43
|
def text_value
|
47
|
-
|
48
|
-
# Something went wrong, lets hack our way through.
|
49
|
-
/\/Text \(˛ˇ(.*)\)$/.match(@data[:text]['EngineData'])[1].gsub /\r/, "\n"
|
50
|
-
else
|
51
|
-
engine_data.EngineDict.Editor.Text
|
52
|
-
end
|
44
|
+
@data[:text]['Txt ']
|
53
45
|
end
|
54
46
|
alias :to_s :text_value
|
55
47
|
|
data/lib/psd/layer_mask.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'psd/resources/base'
|
2
|
+
|
3
|
+
class PSD
|
4
|
+
class Resource
|
5
|
+
module Section
|
6
|
+
class XMPMetadata < Base
|
7
|
+
resource_id 1060
|
8
|
+
name :xmp_metadata
|
9
|
+
|
10
|
+
attr_reader :xml, :data
|
11
|
+
alias_method :to_hash, :data
|
12
|
+
|
13
|
+
def parse
|
14
|
+
@xml = @file.read(@resource.size)
|
15
|
+
@data = {}
|
16
|
+
|
17
|
+
@xmp = XMP.new(xml)
|
18
|
+
@xmp.namespaces.each do |a|
|
19
|
+
parse_tree(a.to_sym)
|
20
|
+
end
|
21
|
+
rescue Java::OrgW3cDom::DOMException
|
22
|
+
PSD.logger.error "Unable to parse XMP Metadata"
|
23
|
+
ensure
|
24
|
+
@resource.data = self
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_tree(attr_name)
|
30
|
+
@data[attr_name] = {}
|
31
|
+
@xmp.send(attr_name).attributes.each do |a|
|
32
|
+
begin
|
33
|
+
@data[attr_name][a.to_sym] = @xmp.send(attr_name).send(a)[0]
|
34
|
+
rescue
|
35
|
+
@data[attr_name][a.to_sym] = parse_text_node(@xmp.send(attr_name), "//#{attr_name}:#{a}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_text_node(node, path)
|
41
|
+
node.send(:xml).xpath(path).first.text
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/psd/version.rb
CHANGED
data/psd.gemspec
CHANGED
@@ -19,9 +19,10 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
21
|
gem.add_dependency 'rake'
|
22
|
-
gem.add_dependency 'psd-enginedata', '~> 1
|
22
|
+
gem.add_dependency 'psd-enginedata', '~> 1'
|
23
23
|
gem.add_dependency 'chunky_png'
|
24
24
|
gem.add_dependency 'activesupport', '~> 3.2.7'
|
25
|
+
gem.add_dependency 'xmp'
|
25
26
|
|
26
27
|
gem.test_files = Dir.glob("spec/**/*")
|
27
28
|
gem.add_development_dependency 'rspec'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: psd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan LeFevre
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '1
|
34
|
+
version: '1'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '1
|
41
|
+
version: '1'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: chunky_png
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 3.2.7
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: xmp
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: rspec
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,7 +154,6 @@ files:
|
|
140
154
|
- LICENSE.txt
|
141
155
|
- README.md
|
142
156
|
- Rakefile
|
143
|
-
- circle.yml
|
144
157
|
- lib/psd.rb
|
145
158
|
- lib/psd/blend_mode.rb
|
146
159
|
- lib/psd/channel_image.rb
|
@@ -223,6 +236,7 @@ files:
|
|
223
236
|
- lib/psd/resources/guides.rb
|
224
237
|
- lib/psd/resources/layer_comps.rb
|
225
238
|
- lib/psd/resources/slices.rb
|
239
|
+
- lib/psd/resources/xmp_metadata.rb
|
226
240
|
- lib/psd/util.rb
|
227
241
|
- lib/psd/version.rb
|
228
242
|
- psd.gemspec
|