psd 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +21 -6
- data/lib/psd.rb +0 -2
- data/lib/psd/blend_mode.rb +4 -3
- data/lib/psd/channel_image.rb +29 -2
- data/lib/psd/clipping_mask.rb +40 -0
- data/lib/psd/color.rb +15 -13
- data/lib/psd/compose.rb +357 -0
- data/lib/psd/file.rb +5 -1
- data/lib/psd/image.rb +9 -0
- data/lib/psd/image_exports/png.rb +54 -1
- data/lib/psd/image_formats/raw.rb +1 -1
- data/lib/psd/image_modes/rgb.rb +4 -1
- data/lib/psd/layer.rb +3 -2
- data/lib/psd/layer/blend_modes.rb +14 -1
- data/lib/psd/layer/blending_ranges.rb +18 -16
- data/lib/psd/layer/helpers.rb +1 -1
- data/lib/psd/layer/info.rb +12 -3
- data/lib/psd/layer_info.rb +3 -2
- data/lib/psd/layer_info/blend_clipping_elements.rb +13 -0
- data/lib/psd/layer_info/blend_interior_elements.rb +13 -0
- data/lib/psd/layer_info/layer_name_source.rb +3 -1
- data/lib/psd/layer_info/vector_mask_2.rb +10 -0
- data/lib/psd/layer_info/vector_stroke.rb +12 -0
- data/lib/psd/layer_info/vector_stroke_content.rb +15 -0
- data/lib/psd/layer_mask.rb +1 -1
- data/lib/psd/layer_styles.rb +84 -0
- data/lib/psd/node.rb +2 -1
- data/lib/psd/node_layer.rb +7 -1
- data/lib/psd/nodes/ancestry.rb +12 -0
- data/lib/psd/nodes/build_preview.rb +69 -0
- data/lib/psd/nodes/search.rb +1 -0
- data/lib/psd/resources/slices.rb +27 -0
- data/lib/psd/version.rb +1 -1
- data/spec/files/slices.psd +0 -0
- data/spec/image_spec.rb +2 -2
- data/spec/slices_spec.rb +52 -0
- metadata +16 -2
data/lib/psd/node.rb
CHANGED
@@ -7,6 +7,7 @@ class PSD
|
|
7
7
|
class Node
|
8
8
|
include Ancestry
|
9
9
|
include Search
|
10
|
+
include BuildPreview
|
10
11
|
|
11
12
|
# Default properties that all nodes contain
|
12
13
|
PROPERTIES = [:name, :left, :right, :top, :bottom, :height, :width]
|
@@ -38,7 +39,7 @@ class PSD
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def group?
|
41
|
-
is_a?(PSD::Node::Group)
|
42
|
+
is_a?(PSD::Node::Group) || is_a?(PSD::Node::Root)
|
42
43
|
end
|
43
44
|
|
44
45
|
def to_hash
|
data/lib/psd/node_layer.rb
CHANGED
@@ -58,7 +58,13 @@ class PSD::Node
|
|
58
58
|
type: :layer,
|
59
59
|
text: @layer.text,
|
60
60
|
ref_x: @layer.reference_point.x,
|
61
|
-
ref_y: @layer.reference_point.y
|
61
|
+
ref_y: @layer.reference_point.y,
|
62
|
+
mask: @layer.mask.snapshot,
|
63
|
+
image: {
|
64
|
+
width: @layer.image.width,
|
65
|
+
height: @layer.image.height,
|
66
|
+
channels: @layer.channels_info
|
67
|
+
}
|
62
68
|
})
|
63
69
|
end
|
64
70
|
|
data/lib/psd/nodes/ancestry.rb
CHANGED
@@ -38,6 +38,18 @@ class PSD
|
|
38
38
|
parent.children
|
39
39
|
end
|
40
40
|
|
41
|
+
def next_sibling
|
42
|
+
return nil if parent.nil?
|
43
|
+
index = siblings.index(self)
|
44
|
+
siblings[index + 1]
|
45
|
+
end
|
46
|
+
|
47
|
+
def prev_sibling
|
48
|
+
return nil if parent.nil?
|
49
|
+
index = siblings.index(self)
|
50
|
+
siblings[index - 1]
|
51
|
+
end
|
52
|
+
|
41
53
|
# Does this node have any siblings?
|
42
54
|
def has_siblings?
|
43
55
|
siblings.length > 1
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class PSD
|
2
|
+
class Node
|
3
|
+
module BuildPreview
|
4
|
+
include PSD::Image::Export::PNG
|
5
|
+
|
6
|
+
alias :orig_to_png :to_png
|
7
|
+
def to_png
|
8
|
+
return build_png if group?
|
9
|
+
layer.image.to_png
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_png(png=nil)
|
13
|
+
png ||= create_canvas
|
14
|
+
|
15
|
+
children.reverse.each do |c|
|
16
|
+
next unless c.visible?
|
17
|
+
|
18
|
+
if c.group?
|
19
|
+
if c.blending_mode == 'passthru'
|
20
|
+
c.build_png(png)
|
21
|
+
else
|
22
|
+
compose! c, png, c.build_png, 0, 0
|
23
|
+
end
|
24
|
+
else
|
25
|
+
compose! c, png, c.image.to_png_with_mask, c.left.to_i, c.top.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
png
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_canvas
|
35
|
+
width, height = document_dimensions
|
36
|
+
ChunkyPNG::Canvas.new(width.to_i, height.to_i, ChunkyPNG::Color::TRANSPARENT)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Modified from ChunkyPNG::Canvas#compose! in order to support various blend modes.
|
40
|
+
def compose!(layer, base, other, offset_x = 0, offset_y = 0)
|
41
|
+
blending_mode = layer.blending_mode.gsub(/ /, '_')
|
42
|
+
PSD.logger.warn("Blend mode #{blending_mode} is not implemented") unless Compose.respond_to?(blending_mode)
|
43
|
+
PSD.logger.debug("Blending #{layer.name} with #{blending_mode} blend mode")
|
44
|
+
|
45
|
+
LayerStyles.new(layer, other).apply!
|
46
|
+
other = ClippingMask.new(layer, other).apply
|
47
|
+
|
48
|
+
for y in 0...other.height do
|
49
|
+
for x in 0...other.width do
|
50
|
+
base_x = x + offset_x
|
51
|
+
base_y = y + offset_y
|
52
|
+
|
53
|
+
next if base_x < 0 || base_y < 0 || base_x >= base.width || base_y >= base.height
|
54
|
+
|
55
|
+
color = Compose.send(
|
56
|
+
blending_mode,
|
57
|
+
other[x, y],
|
58
|
+
base[base_x, base_y],
|
59
|
+
opacity: layer.opacity,
|
60
|
+
fill_opacity: layer.fill_opacity
|
61
|
+
)
|
62
|
+
|
63
|
+
base[base_x, base_y] = color
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/psd/nodes/search.rb
CHANGED
@@ -23,6 +23,7 @@ class PSD
|
|
23
23
|
return matches.map { |m| m.children_at_path(path, opts) }.flatten
|
24
24
|
end
|
25
25
|
end
|
26
|
+
alias :children_with_path :children_at_path
|
26
27
|
|
27
28
|
# Given a layer comp ID, name, or :last for last document state, create a new
|
28
29
|
# tree based on the layers/groups that belong to the comp only.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class PSD
|
2
|
+
class Resource
|
3
|
+
class Section
|
4
|
+
class Slices < Section
|
5
|
+
attr_reader :data, :version
|
6
|
+
|
7
|
+
def self.id; 1050; end
|
8
|
+
def self.name; :slices; end
|
9
|
+
|
10
|
+
def parse
|
11
|
+
@version = @file.read_int
|
12
|
+
@descriptor_version = @file.read_int
|
13
|
+
@resource.data = self
|
14
|
+
|
15
|
+
if @version == 7 || @version == 8
|
16
|
+
@data = Descriptor.new(@file).parse
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_a
|
22
|
+
@data.nil? ? [] : @data['slices']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/psd/version.rb
CHANGED
Binary file
|
data/spec/image_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe 'Image Exporting' do
|
|
28
28
|
|
29
29
|
describe "as PNG" do
|
30
30
|
it "should produce a valid PNG object" do
|
31
|
-
expect(@psd.image.to_png).to be_an_instance_of(ChunkyPNG::
|
31
|
+
expect(@psd.image.to_png).to be_an_instance_of(ChunkyPNG::Canvas)
|
32
32
|
|
33
33
|
expect(@psd.image.to_png.width).to eq(1)
|
34
34
|
expect(@psd.image.to_png.height).to eq(1)
|
@@ -58,7 +58,7 @@ describe 'Image Exporting' do
|
|
58
58
|
@psd.parse!
|
59
59
|
|
60
60
|
png = @psd.tree.children.first.image.to_png
|
61
|
-
expect(png).to be_an_instance_of(ChunkyPNG::
|
61
|
+
expect(png).to be_an_instance_of(ChunkyPNG::Canvas)
|
62
62
|
expect(png.width).to eq(1)
|
63
63
|
expect(png.height).to eq(1)
|
64
64
|
expect(
|
data/spec/slices_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Slices' do
|
4
|
+
|
5
|
+
describe "Handle file with slice properly" do
|
6
|
+
|
7
|
+
|
8
|
+
it "should successfully parse a the PSD file of version 7 or above and has slices" do
|
9
|
+
psd = PSD.new('spec/files/slices.psd')
|
10
|
+
psd.parse!
|
11
|
+
|
12
|
+
# File should parse
|
13
|
+
expect(psd).to be_parsed
|
14
|
+
|
15
|
+
# Slices should not be nil
|
16
|
+
expect(psd.resources[:slices]).to_not be_nil
|
17
|
+
|
18
|
+
# slices version should be above 6
|
19
|
+
expect(psd.resources[:slices].data.version).to be > 6
|
20
|
+
|
21
|
+
# Bounds of each slice should not be nil
|
22
|
+
psd.resources[:slices].data.to_a.each do |slice|
|
23
|
+
expect(slice).to_not be_nil
|
24
|
+
expect(slice['bounds']).to_not be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
it "should successfully parse a the PSD file of version 6 and has slices" do
|
30
|
+
psd = PSD.new('spec/files/pixel.psd')
|
31
|
+
psd.parse!
|
32
|
+
|
33
|
+
# File should parse
|
34
|
+
expect(psd).to be_parsed
|
35
|
+
|
36
|
+
# Slices should still be not nil
|
37
|
+
expect(psd.resources[:slices]).to_not be_nil
|
38
|
+
|
39
|
+
# But slices version should be equal to 6
|
40
|
+
expect(psd.resources[:slices].data.version).to eq 6
|
41
|
+
|
42
|
+
# Slices data to be nil
|
43
|
+
expect(psd.resources[:slices].data.to_a).to eq []
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "Handle file without slices properly" do
|
48
|
+
#TODO: All files have atleast one autogenerated slice. Dunno how to handle this case yet!
|
49
|
+
#it "should successfully parse a PSD file which does not have slices" do
|
50
|
+
#end
|
51
|
+
end
|
52
|
+
end
|
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: 1.
|
4
|
+
version: 1.4.0
|
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: 2013-
|
12
|
+
date: 2013-11-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -144,7 +144,9 @@ files:
|
|
144
144
|
- lib/psd.rb
|
145
145
|
- lib/psd/blend_mode.rb
|
146
146
|
- lib/psd/channel_image.rb
|
147
|
+
- lib/psd/clipping_mask.rb
|
147
148
|
- lib/psd/color.rb
|
149
|
+
- lib/psd/compose.rb
|
148
150
|
- lib/psd/descriptor.rb
|
149
151
|
- lib/psd/file.rb
|
150
152
|
- lib/psd/header.rb
|
@@ -170,6 +172,8 @@ files:
|
|
170
172
|
- lib/psd/layer/path_components.rb
|
171
173
|
- lib/psd/layer/position_and_channels.rb
|
172
174
|
- lib/psd/layer_info.rb
|
175
|
+
- lib/psd/layer_info/blend_clipping_elements.rb
|
176
|
+
- lib/psd/layer_info/blend_interior_elements.rb
|
173
177
|
- lib/psd/layer_info/fill_opacity.rb
|
174
178
|
- lib/psd/layer_info/layer_group.rb
|
175
179
|
- lib/psd/layer_info/layer_id.rb
|
@@ -183,7 +187,11 @@ files:
|
|
183
187
|
- lib/psd/layer_info/typetool.rb
|
184
188
|
- lib/psd/layer_info/unicode_name.rb
|
185
189
|
- lib/psd/layer_info/vector_mask.rb
|
190
|
+
- lib/psd/layer_info/vector_mask_2.rb
|
191
|
+
- lib/psd/layer_info/vector_stroke.rb
|
192
|
+
- lib/psd/layer_info/vector_stroke_content.rb
|
186
193
|
- lib/psd/layer_mask.rb
|
194
|
+
- lib/psd/layer_styles.rb
|
187
195
|
- lib/psd/logger.rb
|
188
196
|
- lib/psd/mask.rb
|
189
197
|
- lib/psd/node.rb
|
@@ -192,6 +200,7 @@ files:
|
|
192
200
|
- lib/psd/node_layer.rb
|
193
201
|
- lib/psd/node_root.rb
|
194
202
|
- lib/psd/nodes/ancestry.rb
|
203
|
+
- lib/psd/nodes/build_preview.rb
|
195
204
|
- lib/psd/nodes/has_children.rb
|
196
205
|
- lib/psd/nodes/lock_to_origin.rb
|
197
206
|
- lib/psd/nodes/parse_layers.rb
|
@@ -201,6 +210,7 @@ files:
|
|
201
210
|
- lib/psd/resource_section.rb
|
202
211
|
- lib/psd/resources.rb
|
203
212
|
- lib/psd/resources/layer_comps.rb
|
213
|
+
- lib/psd/resources/slices.rb
|
204
214
|
- lib/psd/section.rb
|
205
215
|
- lib/psd/util.rb
|
206
216
|
- lib/psd/version.rb
|
@@ -210,12 +220,14 @@ files:
|
|
210
220
|
- spec/files/path.psd
|
211
221
|
- spec/files/pixel.psd
|
212
222
|
- spec/files/simplest.psd
|
223
|
+
- spec/files/slices.psd
|
213
224
|
- spec/files/text.psd
|
214
225
|
- spec/hierarchy_spec.rb
|
215
226
|
- spec/identity_spec.rb
|
216
227
|
- spec/image_spec.rb
|
217
228
|
- spec/parsing_spec.rb
|
218
229
|
- spec/psd_spec.rb
|
230
|
+
- spec/slices_spec.rb
|
219
231
|
- spec/spec_helper.rb
|
220
232
|
- spec/text_spec.rb
|
221
233
|
homepage: http://cosmos.layervault.com/psdrb.html
|
@@ -248,11 +260,13 @@ test_files:
|
|
248
260
|
- spec/files/path.psd
|
249
261
|
- spec/files/pixel.psd
|
250
262
|
- spec/files/simplest.psd
|
263
|
+
- spec/files/slices.psd
|
251
264
|
- spec/files/text.psd
|
252
265
|
- spec/hierarchy_spec.rb
|
253
266
|
- spec/identity_spec.rb
|
254
267
|
- spec/image_spec.rb
|
255
268
|
- spec/parsing_spec.rb
|
256
269
|
- spec/psd_spec.rb
|
270
|
+
- spec/slices_spec.rb
|
257
271
|
- spec/spec_helper.rb
|
258
272
|
- spec/text_spec.rb
|