psd 1.5.0 → 2.0.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/.travis.yml +1 -1
- data/README.md +2 -1
- data/lib/psd.rb +2 -1
- data/lib/psd/blend_mode.rb +5 -1
- data/lib/psd/channel_image.rb +6 -4
- data/lib/psd/header.rb +8 -0
- data/lib/psd/helpers.rb +13 -1
- data/lib/psd/image.rb +1 -1
- data/lib/psd/image_exports/png.rb +2 -70
- data/lib/psd/image_formats/layer_raw.rb +1 -1
- data/lib/psd/image_formats/raw.rb +2 -4
- data/lib/psd/image_modes/cmyk.rb +16 -6
- data/lib/psd/layer/helpers.rb +1 -1
- data/lib/psd/layer_info/fill_opacity.rb +2 -2
- data/lib/psd/logger.rb +7 -1
- data/lib/psd/node.rb +6 -2
- data/lib/psd/node_group.rb +9 -1
- data/lib/psd/node_root.rb +16 -3
- data/lib/psd/nodes/build_preview.rb +7 -69
- data/lib/psd/nodes/search.rb +11 -10
- data/lib/psd/renderer.rb +91 -0
- data/lib/psd/renderer/blender.rb +53 -0
- data/lib/psd/renderer/canvas.rb +95 -0
- data/lib/psd/renderer/canvas_management.rb +26 -0
- data/lib/psd/renderer/clipping_mask.rb +41 -0
- data/lib/psd/{compose.rb → renderer/compose.rb} +23 -19
- data/lib/psd/renderer/layer_styles.rb +56 -0
- data/lib/psd/renderer/layer_styles/color_overlay.rb +65 -0
- data/lib/psd/renderer/layer_styles/drop_shadow.rb +75 -0
- data/lib/psd/renderer/mask.rb +68 -0
- data/lib/psd/resources/guides.rb +35 -0
- data/lib/psd/version.rb +1 -1
- data/psd.gemspec +3 -3
- data/spec/files/blendmodes.psd +0 -0
- data/spec/files/empty-layer-subgroups.psd +0 -0
- data/spec/files/guides.psd +0 -0
- data/spec/guides_spec.rb +34 -0
- data/spec/hierarchy_spec.rb +27 -3
- data/spec/image_spec.rb +36 -35
- data/spec/parsing_spec.rb +13 -0
- metadata +23 -7
- data/lib/psd/clipping_mask.rb +0 -49
- data/lib/psd/layer_styles.rb +0 -84
data/spec/parsing_spec.rb
CHANGED
@@ -147,4 +147,17 @@ describe 'Parsing' do
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
end
|
150
|
+
|
151
|
+
describe 'Blend Modes' do
|
152
|
+
before(:each) do
|
153
|
+
@psd = PSD.new('spec/files/blendmodes.psd')
|
154
|
+
@psd.parse!
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should parse all blend modes" do
|
158
|
+
@psd.layers.each do |layer|
|
159
|
+
expect(layer.blend_mode.mode).to eq layer.name
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
150
163
|
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:
|
4
|
+
version: 2.0.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:
|
12
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '1.0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
57
|
+
name: chunky_png
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - '>='
|
@@ -144,9 +144,7 @@ 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
|
148
147
|
- lib/psd/color.rb
|
149
|
-
- lib/psd/compose.rb
|
150
148
|
- lib/psd/descriptor.rb
|
151
149
|
- lib/psd/file.rb
|
152
150
|
- lib/psd/header.rb
|
@@ -192,7 +190,6 @@ files:
|
|
192
190
|
- lib/psd/layer_info/vector_stroke.rb
|
193
191
|
- lib/psd/layer_info/vector_stroke_content.rb
|
194
192
|
- lib/psd/layer_mask.rb
|
195
|
-
- lib/psd/layer_styles.rb
|
196
193
|
- lib/psd/lazy_execute.rb
|
197
194
|
- lib/psd/logger.rb
|
198
195
|
- lib/psd/mask.rb
|
@@ -208,17 +205,31 @@ files:
|
|
208
205
|
- lib/psd/nodes/parse_layers.rb
|
209
206
|
- lib/psd/nodes/search.rb
|
210
207
|
- lib/psd/path_record.rb
|
208
|
+
- lib/psd/renderer.rb
|
209
|
+
- lib/psd/renderer/blender.rb
|
210
|
+
- lib/psd/renderer/canvas.rb
|
211
|
+
- lib/psd/renderer/canvas_management.rb
|
212
|
+
- lib/psd/renderer/clipping_mask.rb
|
213
|
+
- lib/psd/renderer/compose.rb
|
214
|
+
- lib/psd/renderer/layer_styles.rb
|
215
|
+
- lib/psd/renderer/layer_styles/color_overlay.rb
|
216
|
+
- lib/psd/renderer/layer_styles/drop_shadow.rb
|
217
|
+
- lib/psd/renderer/mask.rb
|
211
218
|
- lib/psd/resource.rb
|
212
219
|
- lib/psd/resource_section.rb
|
213
220
|
- lib/psd/resources.rb
|
221
|
+
- lib/psd/resources/guides.rb
|
214
222
|
- lib/psd/resources/layer_comps.rb
|
215
223
|
- lib/psd/resources/slices.rb
|
216
224
|
- lib/psd/section.rb
|
217
225
|
- lib/psd/util.rb
|
218
226
|
- lib/psd/version.rb
|
219
227
|
- psd.gemspec
|
228
|
+
- spec/files/blendmodes.psd
|
229
|
+
- spec/files/empty-layer-subgroups.psd
|
220
230
|
- spec/files/empty-layer.psd
|
221
231
|
- spec/files/example.psd
|
232
|
+
- spec/files/guides.psd
|
222
233
|
- spec/files/locked.psd
|
223
234
|
- spec/files/one_layer.psd
|
224
235
|
- spec/files/path.psd
|
@@ -226,6 +237,7 @@ files:
|
|
226
237
|
- spec/files/simplest.psd
|
227
238
|
- spec/files/slices.psd
|
228
239
|
- spec/files/text.psd
|
240
|
+
- spec/guides_spec.rb
|
229
241
|
- spec/hierarchy_spec.rb
|
230
242
|
- spec/image_spec.rb
|
231
243
|
- spec/lazy_execute_spec.rb
|
@@ -255,13 +267,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
267
|
version: '0'
|
256
268
|
requirements: []
|
257
269
|
rubyforge_project:
|
258
|
-
rubygems_version: 2.1
|
270
|
+
rubygems_version: 2.2.1
|
259
271
|
signing_key:
|
260
272
|
specification_version: 4
|
261
273
|
summary: General purpose library for parsing Photoshop files
|
262
274
|
test_files:
|
275
|
+
- spec/files/blendmodes.psd
|
276
|
+
- spec/files/empty-layer-subgroups.psd
|
263
277
|
- spec/files/empty-layer.psd
|
264
278
|
- spec/files/example.psd
|
279
|
+
- spec/files/guides.psd
|
265
280
|
- spec/files/locked.psd
|
266
281
|
- spec/files/one_layer.psd
|
267
282
|
- spec/files/path.psd
|
@@ -269,6 +284,7 @@ test_files:
|
|
269
284
|
- spec/files/simplest.psd
|
270
285
|
- spec/files/slices.psd
|
271
286
|
- spec/files/text.psd
|
287
|
+
- spec/guides_spec.rb
|
272
288
|
- spec/hierarchy_spec.rb
|
273
289
|
- spec/image_spec.rb
|
274
290
|
- spec/lazy_execute_spec.rb
|
data/lib/psd/clipping_mask.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
class PSD
|
2
|
-
class ClippingMask
|
3
|
-
def initialize(layer, png=nil)
|
4
|
-
@layer = layer
|
5
|
-
@png = png
|
6
|
-
end
|
7
|
-
|
8
|
-
def apply
|
9
|
-
return @png unless @layer.clipped?
|
10
|
-
|
11
|
-
PSD.logger.debug "Applying clipping mask #{mask.name} to #{@layer.name}"
|
12
|
-
|
13
|
-
width, height = @layer.document_dimensions
|
14
|
-
full_png = compose_to_full
|
15
|
-
|
16
|
-
height.times do |y|
|
17
|
-
width.times do |x|
|
18
|
-
if y < mask.top || y > mask.bottom || x < mask.left || x > mask.right
|
19
|
-
alpha = 0
|
20
|
-
else
|
21
|
-
mask_x = x - mask.left
|
22
|
-
mask_y = y - mask.top
|
23
|
-
|
24
|
-
pixel = mask.image.pixel_data[mask_y * mask.width + mask_x]
|
25
|
-
alpha = pixel.nil? ? 0 : ChunkyPNG::Color.a(pixel)
|
26
|
-
end
|
27
|
-
|
28
|
-
color = full_png[x, y]
|
29
|
-
full_png[x, y] = (color & 0xffffff00) | (ChunkyPNG::Color.a(color) * alpha / 255)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
full_png.crop!(@layer.left, @layer.top, @layer.width, @layer.height)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def mask
|
39
|
-
@mask ||= @layer.next_sibling
|
40
|
-
end
|
41
|
-
|
42
|
-
def compose_to_full
|
43
|
-
width, height = @layer.document_dimensions
|
44
|
-
full_png = ChunkyPNG::Canvas.new(width.to_i, height.to_i, ChunkyPNG::Color::TRANSPARENT)
|
45
|
-
full_png.compose!(@png, @layer.left, @layer.top)
|
46
|
-
full_png
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
data/lib/psd/layer_styles.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
class PSD
|
2
|
-
class LayerStyles
|
3
|
-
# Blend modes in layer effects use different keys
|
4
|
-
# than normal layer blend modes. Thanks Adobe.
|
5
|
-
BLEND_TRANSLATION = {
|
6
|
-
'Nrml' => 'norm',
|
7
|
-
'Dslv' => 'diss',
|
8
|
-
'Drkn' => 'dark',
|
9
|
-
'Mltp' => 'mul',
|
10
|
-
'CBrn' => 'idiv',
|
11
|
-
'linearBurn' => 'lbrn',
|
12
|
-
'Lghn' => 'lite',
|
13
|
-
'Scrn' => 'scrn',
|
14
|
-
'CDdg' => 'div',
|
15
|
-
'linearDodge' => 'lddg',
|
16
|
-
'Ovrl' => 'over',
|
17
|
-
'SftL' => 'sLit',
|
18
|
-
'HrdL' => 'hLit',
|
19
|
-
'vividLight' => 'vLit',
|
20
|
-
'linearLight' => 'lLit',
|
21
|
-
'pinLight' => 'pLit',
|
22
|
-
'hardMix' => 'hMix',
|
23
|
-
'Dfrn' => 'diff',
|
24
|
-
'Xclu' => 'smud',
|
25
|
-
'H ' => 'hue',
|
26
|
-
'Strt' => 'sat',
|
27
|
-
'Clr ' => 'colr',
|
28
|
-
'Lmns' => 'lum'
|
29
|
-
}
|
30
|
-
|
31
|
-
attr_reader :layer, :data, :png
|
32
|
-
|
33
|
-
def initialize(layer, png=nil)
|
34
|
-
@layer = layer
|
35
|
-
@data = layer.info[:object_effects]
|
36
|
-
@png = png || layer.image.to_png
|
37
|
-
|
38
|
-
if @data.nil?
|
39
|
-
@applied = true
|
40
|
-
else
|
41
|
-
@data = @data.data
|
42
|
-
@applied = false
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def apply!
|
47
|
-
return png if @applied || data.nil?
|
48
|
-
|
49
|
-
apply_color_overlay if data.has_key?('SoFi')
|
50
|
-
png
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def apply_color_overlay
|
56
|
-
overlay_data = data['SoFi']
|
57
|
-
color_data = overlay_data['Clr ']
|
58
|
-
blending_mode = BlendMode::BLEND_MODES[BLEND_TRANSLATION[overlay_data['Md ']].to_sym]
|
59
|
-
|
60
|
-
width = layer.width.to_i
|
61
|
-
height = layer.height.to_i
|
62
|
-
|
63
|
-
PSD.logger.debug("Layer style: layer = #{layer.name}, type = color overlay, blend mode = #{blending_mode}")
|
64
|
-
|
65
|
-
for y in 0...height do
|
66
|
-
for x in 0...width do
|
67
|
-
pixel = png.get_pixel(x, y)
|
68
|
-
alpha = ChunkyPNG::Color.a(pixel)
|
69
|
-
next if alpha == 0
|
70
|
-
|
71
|
-
overlay_color = ChunkyPNG::Color.rgba(
|
72
|
-
color_data['Rd '].round,
|
73
|
-
color_data['Grn '].round,
|
74
|
-
color_data['Bl '].round,
|
75
|
-
alpha
|
76
|
-
)
|
77
|
-
|
78
|
-
color = Compose.send(blending_mode, overlay_color, pixel)
|
79
|
-
png.set_pixel(x, y, color)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|