Giter Site home page Giter Site logo

psd.rb's Introduction

PSD.rb

Travis CI

A general purpose Photoshop file parser written in Ruby. It allows you to work with a Photoshop document in a manageable tree structure and find out important data such as:

  • Document structure
  • Document size
  • Layer/folder size + positioning
  • Layer/folder names
  • Layer/folder visibility and opacity
  • Font data (via psd-enginedata)
    • Text area contents
    • Font names, sizes, and colors
  • Color mode and bit-depth
  • Vector mask data
  • Flattened image data
  • Layer comps

PSD.rb is tested against:

  • MRI 1.9.3, 2.0.0, 2.1.0
  • JRuby (1.9.3 mode)

If you use MRI Ruby and are interested in significantly speeding up PSD.rb with native code, check out psd_native.

Installation

Add this line to your application's Gemfile:

gem 'psd'

And then execute:

$ bundle

Or install it yourself as:

$ gem install psd

Usage

The full source code documentation is available, but here are some common ways to use and access the PSD data:

Loading a PSD

require 'psd'

psd = PSD.new('/path/to/file.psd')
psd.parse!

Or, if you prefer the File.open way of doing things, you can do that too.

require 'psd'

PSD.open('path/to/file.psd') do |psd|
  p psd.tree.to_hash
end

As you can see, open calls parse! for you, so that you can get down to business right away.

If you happen to prefer things DSL-style, the open method will also let you operate on the PSD object directly. Again, the call to parse! is handled for you.

require 'psd'

PSD.open('path/to/file.psd') do
  p tree.to_hash
end

Traversing the Document

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:

  • root: get the root node from anywhere in the tree
  • root?: is this the root node?
  • children: get all immediate children of the node
  • has_children?: does this node have any children?
  • childless?: opposite of has_children?
  • ancestors: get all ancestors in the path of this node (excluding the root)
  • siblings: get all sibling tree nodes including the current one (e.g. all layers in a folder)
  • next_sibling: gets the sibling immediately following the current node
  • prev_sibling: gets the sibling immediately before the current node
  • has_siblings?: does this node have any siblings?
  • only_child?: opposite of has_siblings?
  • descendants: get all descendant nodes not including the current one
  • subtree: same as descendants but starts with the current node
  • depth: calculate the depth of the current node (root node is 0)
  • path: gets the path to the current node

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:

psd.tree.descendant_layers

If you know the path to a group or layer within the tree, you can search by that path. Note that this always returns an Array because layer/group names do not have to be unique.

psd.tree.children_at_path("Version A/Matte")
psd.tree.children_at_path(["Version A", "Matte"])

Layer Comps

You can also filter nodes based on a layer comp. To generate a new tree with layer visibility and position set according to the layer comp data:

# Get information about all the available layer comps
puts psd.layer_comps

# Can filter by name or by ID (obtained from above)
tree = psd.tree.filter_by_comp('Version A')
puts tree.children.map(&:name)

This returns a new node tree and does not alter the original.

Accessing Layer Data

To get data such as the name or dimensions of a layer:

psd.tree.descendant_layers.first.name
psd.tree.descendant_layers.first.width

PSD files also store various pieces of information in "layer info" blocks. Which blocks a layer has varies from layer-to-layer, but to access them you can do:

psd.tree.descendant_layers.first.text[:font]

# Returns
{:name=>"HelveticaNeue-Light",
 :sizes=>[33.0],
 :colors=>[[255, 19, 120, 98]],
 :css=>
  "font-family: \"HelveticaNeue-Light\", \"AdobeInvisFont\", \"MyriadPro-Regular\";\nfont-size: 33.0pt;\ncolor: rgba(19, 120, 98, 255);"}

Exporting Data

When working with the tree structure, you can recursively export any node to a Hash.

pp psd.tree.to_hash

Which produces something like:

{:children=>
  [{:type=>:group,
    :visible=>false,
    :opacity=>1.0,
    :blending_mode=>"normal",
    :name=>"Version D",
    :left=>0,
    :right=>900,
    :top=>0,
    :bottom=>600,
    :height=>900,
    :width=>600,
    :children=>
     [{:type=>:layer,
       :visible=>true,
       :opacity=>1.0,
       :blending_mode=>"normal",
       :name=>"Make a change and save.",
       :left=>275,
       :right=>636,
       :top=>435,
       :bottom=>466,
       :height=>31,
       :width=>361,
       :text=>
        {:value=>"Make a change and save.",
         :font=>
          {:name=>"HelveticaNeue-Light",
           :sizes=>[33.0],
           :colors=>[[255, 19, 120, 98]],
           :css=>
            "font-family: \"HelveticaNeue-Light\", \"AdobeInvisFont\", \"MyriadPro-Regular\";\nfont-size: 33.0pt;\ncolor: rgba(19, 120, 98, 255);"},
         :left=>0,
         :top=>0,
         :right=>0,
         :bottom=>0,
         :transform=>
          {:xx=>1.0, :xy=>0.0, :yx=>0.0, :yy=>1.0, :tx=>456.0, :ty=>459.0}},
       :ref_x=>264.0,
       :ref_y=>-3.0}]
  }],
:document=>{:width=>900, :height=>600}}

You can also export the PSD to a flattened image. Please note that, at this time, not all image modes + depths are supported.

png = psd.image.to_png # reference to PNG data
psd.image.save_as_png 'path/to/output.png' # writes PNG to disk

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.

Preview Building

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.

# Save a layer comp
psd.tree.filter_by_comp("Version A").save_as_png('./Version A.png')

# Generate PNG of individual layer group
psd.tree.children_at_path("Group 1").first.to_png

Slices

Because slices are relative to the full document, you can access them directly on the psd object. Use psd.slices to get an array of all slices in the document.

slices = psd.slices
slices.first.name #=> "Logo"
slices.first.left #=> 20
slices.first.width #=> 200

You can also search for slices if you know their name or ID. Because slice names do not need to be unique, slices_by_name will always return an array of all matches.

psd.slice_by_id(2)
psd.slices_by_name('Logo')

When you create a slice based off of a layer, Photoshop stores this relation in the file. If you have a slice that was created this way, you can easily get the associated layer.

slice = psd.slices_by_name('Logo').first
slice.associated_layer #=> <PSD::Node::Layer>

Finally, you can export slices as PNGs.

psd.slices.first.to_png #=> ChunkyPNG canvas
psd.slices_by_name('Logo').first.save_as_png('Logo.png') #=> writes Logo.png

Debugging

If you run into any problems parsing a PSD, you can enable debug logging via the PSD_DEBUG environment variable. For example:

PSD_DEBUG=true bundle exec examples/parse.rb

If you need to enable debugging programatically:

PSD.debug = true

To-do

There are a few features that are currently missing from PSD.rb.

  • More image modes + depths for image exporting
  • Support for rendering all layer styles
  • Support for layer comp adjusted layer styles
  • Render engine fixes for groups with lowered opacity

psd.rb's People

Contributors

adamcw avatar analogj avatar bfoz avatar catmando avatar chuyyei avatar jake avatar jeremyckahn avatar kellysutton avatar loginovilya avatar mc-jordan-andree avatar meltingice avatar redcap97 avatar rstacruz avatar surenm avatar teejteej avatar tomashanacek avatar ungsophy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

psd.rb's Issues

IOError: closed stream when saving to PNG

Saving example.psd to a PNG throws an error, however the image appears to be generated correctly despite the error. Error output is below.

Here's my ruby version:
09:32 bfoz@nancy-dt:test$ ruby --version
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]

Here's the error:

09:10 bfoz@nancy-dt:test$ irb

require 'psd'
true
psd = PSD.new 'example.psd'

<PSD:0x007fe09418ff70 @file=#PSD::File:example.psd, @opts={:parse_image=>false, :parse_layer_images=>false}, @Header=nil, @resources=nil, @layer_mask=nil, @parsed=false>

psd.image.save_as_png 'example.png'
IOError: closed stream
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/formatter.rb:191:in directory?' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/formatter.rb:191:inawesome_file'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/formatter.rb:26:in format' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/inspector.rb:137:inunnested'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/inspector.rb:104:in awesome' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/core_ext/kernel.rb:10:inai'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/core_ext/kernel.rb:15:in ap' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/awesome_print-1.1.0/lib/awesome_print/inspector.rb:31:inoutput_value'
from /Users/bfoz/.rvm/rubies/ruby-1.9.3-p448/bin/irb:16:in `

'

Layer/group locked info

Hi,

Is it possible to parse if a layer or group is locked or not? I'm not sure if this is possible at all, as a quick peek into the PSD file format specs didn't show anything relevant.

Question: Individual layer image exporting

I see this as part of the "to do" list. What's the progress on it? Has it been started? Is it planned to be started? If I'm to contribute patches to make that happen, any pointers on where should I start?

I'd love to have this feature and I'm open to implementing it on my own.

tree.to_hash giving error

I am just new to this psd,rb. After read readme I started using like below
PSD.open('path/to/file') do
p tree.to_hash
end
getting below error

ruby-1.9.3-p392@rails3tutorial/gems/psd-1.4.5/lib/psd/layer.rb:74:in method_missing': undefined methodreference_point' for #PSD::Layer:0x00000001cc9420 (NoMethodError)

Can't get anything to work

I've used various PSD files, both from myself and others, and one of a few things always happens:
None of the layers are found (psd.layers is an empty array)
NoMethodError: undefined method delete' for nil:NilClass when I run psd.parse! NoMethodError: undefined methodunpack' for nil:NilClass when I run psd.parse!
and more

I literally haven't gotten one document to work. I'm using Photoshop CS6.

Channel Image data is fails to parse when compression is > 3

It's valid to have channel image data when the Compression value is > 3. See: http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_26431

Because this value is odd, it signifies that the following data will require some padding at the end of its row. I'm working on producing a PSD that illustrates this problem.

It should also be noted that the method #parse_image_data! should be reading a an unsigned short, instead of calling parse_compression!. Compression values come in other shapes and sizes. This is the PSD, after all.

Parsing failed

Here is the psd file: http://d.pr/f/ThK2

NoMethodError: undefined method `unpack' for nil:NilClass
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/file.rb:44:in `block (2 levels) in <class:File>'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer.rb:278:in `block in parse_blending_ranges'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer.rb:270:in `times'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer.rb:270:in `parse_blending_ranges'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer.rb:67:in `parse'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer_mask.rb:53:in `block in parse'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer_mask.rb:52:in `times'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd/layer_mask.rb:52:in `parse'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd.rb:90:in `layer_mask'
    from /Users/liujin/.rvm/gems/ruby-2.0.0-p0/gems/psd-0.3.4/lib/psd.rb:54:in `parse!'
    from (irb):7
    from /Users/liujin/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in `<main>'

undefined method `parse_zip!'

/Users/tomashanacek/Documents/projects/psd.rb/lib/psd/channel_image.rb:90:in `parse_image_data!': undefined method `parse_zip!' for #<PSD::ChannelImage:0x007f9c45a05f58> (NoMethodError)
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/channel_image.rb:63:in `block in parse'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/channel_image.rb:42:in `each'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/channel_image.rb:42:in `parse'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/lazy_execute.rb:58:in `load!'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/lazy_execute.rb:39:in `method_missing'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/renderer/canvas.rb:13:in `initialize'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/renderer/canvas_management.rb:10:in `new'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/renderer/canvas_management.rb:10:in `create_group_canvas'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/renderer.rb:27:in `render!'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/renderer.rb:66:in `to_png'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/nodes/build_preview.rb:9:in `to_png'
    from /Users/tomashanacek/Documents/projects/psd.rb/lib/psd/nodes/build_preview.rb:13:in `save_as_png'

Layer section divider not being properly parsed

I am unsure if this is due to a newer psd version, but I am getting layers that have the name </Layer group> but that are marked as 'normal' - after some debugging I found that they do not have an lsct data key, but they do have lsdk, which I can't seem to find anywhere, even in the adobe documentation. Have you ever seen this?

here is the layer hash:

{:type => :layer, :visible => true, :opacity => 1.0, :blending_mode => "normal", :name => "</Layer group>", :left => 0, :right => 0, :top => 0, :bottom => 0, :height => 0, :width => 0, :text => nil, :ref_x => 189.25, :ref_y => 142.5}

note, this is from the psd.tree.to_hash method, which I believe usually excludes layer dividers.

PNG exporting speed improvements

Exporting to PNG is a bit slow right now. There are likely many areas for improvement within PSD.rb itself that can help speed up this process.

Exporting mask path values

Is there a way to pull out layer mask path vertices? I know the values are available in the psd document structure and I could pull them out myself. Just wondering if there is already a way to get these to show up in the psd hash?

Layer fill colors?

I can't find any information on fill color for a Solid Fill Layers. The parser only seems to parse text layr color. Is solid layer color not being parsed?

bignum too big to convert into `long' (RangeError)

C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/file.rb:80:in `read': bignum too big to convert into `long' (RangeError)
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/file.rb:80:in `read_unicode_string'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:31:in `parse_class'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:119:in `parse_object_array'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:126:in `block (2 levels) in parse_object_array'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:125:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:125:in `block in parse_object_array'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:123:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:123:in `parse_object_array'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:62:in `parse_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:43:in `parse_key_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:20:in `block in parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:54:in `parse_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:43:in `parse_key_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:20:in `block in parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:54:in `parse_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:43:in `parse_key_item'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:20:in `block in parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_info/placed_layer.rb:11:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:314:in `block in parse_extra_data'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:310:in `each'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:310:in `parse_extra_data'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:69:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:53:in `block in parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd.rb:90:in `layer_mask'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd.rb:54:in `parse!'
        from ./do.rb:3:in `<main>'

https://dl.dropboxusercontent.com/u/9264537/like.psd

Handling large files to parse

I am parsing > 500mb PSDs, I am looking at some strategies for mitigating the processing time. Just wondering if you have come up with any ideas for handling this.

Is it possible to resize image?

psd = PSD.new('path/to/psd', parse_image_layers: true)
psd.parse!

new_psd = psd.resize(new_width, new_height)

# or

psd.resize!(new_width, new_height)

I looked around at the source code, but seems like this feature is not implemented yet.

Encoding::UndefinedConversionError: "\xA9" from ASCII-8BIT to UTF-8

irb(main):003:0> psd = PSD.new('0002_Header_Redesign.psd')
=> #<PSD:0x2f08ed8 @file=#<PSD::File:0002_Header_Redesign.psd>, @opts={:parse_image=>false, :parse_layer_images=>false}, @header=nil, @resources=nil, @layer_mask=nil, @parsed=false>
irb(main):005:0> psd.parse!
Encoding::UndefinedConversionError: "\xA9" from ASCII-8BIT to UTF-8
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_info/unicode_name.rb:10:in `encode'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_info/unicode_name.rb:10:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:314:in `block in parse_extra_data'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:310:in `each'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:310:in `parse_extra_data'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer.rb:69:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:53:in `block in parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:in `times'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:in `parse'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd.rb:90:in `layer_mask'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems/psd-0.3.3/lib/psd.rb:54:in `parse!'
        from (irb):5
        from C:/Ruby200/bin/irb:12:in `<main>'

Does Guard need to be a development dependency?

Sure, guard is great and all, but not everyone uses it. Does it really need to be listed as a development dependency?

Making guard a dependency forces 'bundle install' to install it, and not everyone wants that. I don't mind, but I can see how others might.

I'm happy to make the change and submit a pull request.

Max Compatibility Layer

I love this project. Thank you. Is there any way to detect if a max compatibility layer is saved into the file?

Layer mask problem

Encountered this with a file with a simple bitmap layer mask.

/Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd/channel_image.rb:69:in `parse': undefined local variable or method `channel_data' for #<PSD::ChannelImage:0x00000105710308> (NameError)
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd/layer.rb:101:in `parse_channel_image!'
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd/layer_mask.rb:59:in `block in parse'
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd/layer_mask.rb:57:in `each'
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd/layer_mask.rb:57:in `parse'
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd.rb:116:in `layer_mask'
        from /Users/rsc/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/psd-1.1.1/lib/psd.rb:75:in `parse!'
        from /Users/rsc/tmp/psd/lib/psdtool/document.rb:12:in `initialize'
        from psd.rb:5:in `new'
        from psd.rb:5:in `<main>'

No method error FontSize

Hey there, I have found with certain psds, I get a undefined method 'FontSize' for #<PSD::EngineData::Node:0x007fc9110b3740>

This looks like its happening at this point psdHash = psd.tree.to_hash.

Is this a known bug or do you know why it's happening.

Cheers
Sam

"\xF0" to UTF-8 in conversion from macRoman to UTF-8 (Encoding::UndefinedConversionError)

/Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/file.rb:75:in `encode': "\xF0" to UTF-8 in conversion from macRoman to UTF-8 (Encoding::UndefinedConversionError)
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/file.rb:75:in `read_string'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/layer.rb:294:in `parse_legacy_layer_name'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/layer.rb:69:in `parse'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/layer_mask.rb:54:in `block in parse'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/layer_mask.rb:53:in `times'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd/layer_mask.rb:53:in `parse'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd.rb:116:in `layer_mask'
    from /Users/weiwei/.rvm/gems/ruby-2.0.0-p195/gems/psd-1.3.2/lib/psd.rb:75:in `parse!'
    from parse.rb:5:in `<main>'

PSD to PNG output is inverted and... very strange

Hello,

I was sharing some frustration on twitter the other night while trying to do some image processing stuff for a project. @meltingice replied to my tweet and suggested that I open an issue here. I'd love to help you guys improve the project as this is a really amazing project and if it worked in my particular case I would have saved a ton of time and also been able to build a bit more advanced solution.

My Workflow

I was trying to open a PSD and then export a high-resolution PNG. Equivalent to opening the PSD in the Photoshop application, Save As PNG, and close the file. Nothing too crazy.

I tested this bug with a handful of files from this page and all of them seem to produce the same result. The specific image I will reference for this issue is ARBESKO_695.psd โ€“ Link to file

PSD as viewed in Photoshop CC

photoshop_screenshot

Output from PSD.rb

psd_rb_export

Here is my IRB Session

irb(main):001:0> require 'psd'
=> true
irb(main):002:0> PSD::VERSION
=> "1.3.0"
irb(main):003:0> shoe = PSD.new('/Users/michael/Downloads/ARBESKO_695.psd')
=> #<PSD:0x007fcad3d53590 @file=#<PSD::File:/Users/michael/Downloads/ARBESKO_695.psd>, @opts={:parse_image=>false, :parse_layer_images=>false}, @header=nil, @resources=nil, @layer_mask=nil, @parsed=false>
irb(main):004:0> shoe.image.save_as_png '/Users/michael/Desktop/arbesko_695.png'
=> #<File:/Users/michael/Desktop/arbesko_695.png (closed)>

I'm not really sure how this is happening. I've tried to pull that inverted png into Photoshop to "reverse engineer" it back into the original but can't seem to get that to happen. It looks like there are some missing channels or something?

My Environment

I'm running OS X 10.9 (hopefully this isn't the main reason). I'm also using ruby 2.0.0p195 installed via rbenv. Let me know if anything else from my env would be helpful.

Exporting mask path values

Is there a way to pull out layer mask path vertices? I know the values are available in the psd document structure and I could pull them out myself. Just wondering if there is already a way to get these to show up in the psd hash?

Error when saving PSD as PNG

Successfully parsed a PSD (attached) but when attempting to save_as_png, I get an error.

1.9.3p286 :015 > psd = PSD.new 'cards.psd'
 => #<PSD:0x007f867b83a758 @file=#<PSD::File:cards.psd>, @opts={:parse_image=>false, :parse_layer_images=>false}, @header=nil, @resources=nil, @layer_mask=nil, @parsed=false>
1.9.3p286 :016 > psd.parse!
 => true
1.9.3p286 :014 > psd.image.save_as_png 'cards.png'
NoMethodError: undefined method `<<' for nil:NilClass
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/chunky_png-1.2.8/lib/chunky_png/color.rb:93:in `rgba'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/psd-0.3.3/lib/psd/image_exports/png.rb:15:in `block (2 levels) in to_png'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/bindata-1.5.0/lib/bindata/base_primitive.rb:115:in `times'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/bindata-1.5.0/lib/bindata/base_primitive.rb:115:in `method_missing'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/psd-0.3.3/lib/psd/image_exports/png.rb:14:in `block in to_png'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/bindata-1.5.0/lib/bindata/base_primitive.rb:115:in `times'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/bindata-1.5.0/lib/bindata/base_primitive.rb:115:in `method_missing'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/psd-0.3.3/lib/psd/image_exports/png.rb:13:in `to_png'
    from /Users/erikdungan/.rvm/gems/ruby-1.9.3-p286@psd/gems/psd-0.3.3/lib/psd/image_exports/png.rb:32:in `save_as_png'
    from (irb):14
    from /Users/erikdungan/.rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>'

I'm on Ruby 1.9.3

The file in question is available at:
http://cloud.bigfolio.com/cards.psd
(in case you want to take a look)

Enhancement: Export all text layers to a plain text document

I've wanted PS to do this for years but this feature never made it in. It would be very helpful, when transforming PSD compositions into HTML/CSS (or other similar tasks), to be able to extract all of the text nodes at one time. Manually opening the PSD in PS, clicking on the Text tool, selecting the text and then Copy/Paste takes up a lot of time; especially if there are many, small, individual text nodes placed in the documents. If this tool could open the PSD and combine all of the text into 1 plain text document with line breaks for separation... it make that task exponentially easier.

Layer Adjustments

I've inspected the adjustments into a more readable format (https://gist.github.com/MattNewberry/94e59e8965af0d94411b) and am curious for feedback on how to better organize these.

These attributes are for a gradient layer adjustment and though I see the RGB values and angles represented, am unclear of the organization of the attribute structure in this format.

Can you assist with guidance on how to better format the attributes into a more digestable matter? I'm happy to tackle this and contribute back to the project.

LoadError: cannot load such file -- oily_png/oily_png

For some reason I have just updated my bundle and Im receiving the following error.
LoadError: cannot load such file -- oily_png/oily_png.

On my other system it is all running fine, so Im not sure what could be causing the error.
Here is the stacktrace:

/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/oily_png-1.1.0/lib/oily_png.rb:19:in `require'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/oily_png-1.1.0/lib/oily_png.rb:19:in `<top (required)>'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd/image_exports/png.rb:1:in `require'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd/image_exports/png.rb:1:in `<top (required)>'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:15:in `require'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:15:in `block (2 levels) in <top (required)>'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:15:in `glob'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:15:in `block in <top (required)>'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:14:in `each'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/psd-1.0.0/lib/psd.rb:14:in `<top (required)>'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `require'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `block (2 levels) in require'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `each'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `block in require'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `each'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `require'
/Users/sam/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler.rb:132:in `require'
config.ru:3:in `block in inner_app'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `inner_app'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:112:in `eval'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:112:in `inner_app'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:102:in `assemble_app'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:86:in `proceed_as_child'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:31:in `call!'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/loader.rb:18:in `call'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/favicon.rb:12:in `call'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/shotgun-0.9/lib/shotgun/static.rb:14:in `call'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:138:in `call'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/puma-2.5.1/lib/puma/server.rb:472:in `handle_request'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/puma-2.5.1/lib/puma/server.rb:343:in `process_client'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/puma-2.5.1/lib/puma/server.rb:242:in `block in run'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/puma-2.5.1/lib/puma/thread_pool.rb:92:in `call'
/Users/sam/Sites/psdfonts/vendor/bundle/ruby/2.0.0/gems/puma-2.5.1/lib/puma/thread_pool.rb:92:in `block in spawn_thread'

example/layer_comps.rb error with my psd file

When I try to run the layer_comps.rb example with a certain psd file I get the following error:

/Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/chunky_png-1.2.9/lib/chunky_png/canvas.rb:312:in `assert_xy!': Coordinates (-1,-2) out of bounds! (ChunkyPNG::OutOfBounds)
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/chunky_png-1.2.9/lib/chunky_png/canvas.rb:132:in `[]='
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:39:in `block (2 levels) in to_png_with_mask'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:38:in `times'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:38:in `block in to_png_with_mask'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:37:in `times'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:37:in `to_png_with_mask'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:25:in `block in build_png'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:15:in `each'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:15:in `build_png'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:20:in `block in build_png'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:15:in `each'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:15:in `build_png'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/nodes/build_preview.rb:8:in `to_png'
    from /Users/gduquesnay/.rvm/gems/ruby-2.0.0-p247/gems/psd-1.4.2/lib/psd/image_exports/png.rb:80:in `save_as_png'
    from examples/layer_comps.rb:15:in `block (2 levels) in <main>'
    from examples/layer_comps.rb:11:in `each'
    from examples/layer_comps.rb:11:in `block in <main>'
    from /Users/gduquesnay/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/benchmark.rb:281:in `measure'
    from examples/layer_comps.rb:7:in `<main>'

I'd appreciate any advice. I also ran it with the PSD_DEBUG=STDOUT but I don't know how to make sense of the output. I can provide the PSD and the debug output if it helps.

Can't open any psd file

Hello! first at all, your project is awesome!

I'm trying to use the gem, however this exception appears on any psd file:

DEBUG: {"sig"=>"8BPS", "version"=>1, "channels"=>4, "rows"=>500, "cols"=>500, "depth"=>8, "mode"=>3, "color_data_len"=>0}

/Users/Choy/.rvm/gems/ruby-1.9.2-p320/gems/psd-1.3.0/lib/psd/file.rb:75:in read_string': undefined methodencode' for nil:NilClass (NoMethodError)

I'm not sure what is wrong.

Thanks ๐Ÿ‘

Chuy

Parsing a particular PSD fails

I have a PSD file that's a mock for an iOS app that I'm working on. When I try parsing it, I get the errors listed below. I'd be happy to provide the errant file, but it's too large to attach to this issue. If there's some other way I can send it to you, please let me know.

psd = PSD.new '1-Splash.psd'

<PSD:0x007fd86bc15ac0 @file=#PSD::File:1-Splash.psd, @opts={:parse_image=>false, :parse_layer_images=>false}, @Header=nil, @resources=nil, @layer_mask=nil, @parsed=false>

psd.parse!
Errno::EINVAL: Invalid argument - 1-Splash.psd
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/file.rb:80:in read' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/file.rb:80:inread_unicode_string'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:31:in parse_class' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:119:inparse_object_array'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:126:in block (2 levels) in parse_object_array' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:125:intimes'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:125:in block in parse_object_array' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:123:intimes'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:123:in parse_object_array' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:62:inparse_item'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:43:in parse_key_item' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:20:inblock in parse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in times' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:19:inparse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:54:in parse_item' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:43:inparse_key_item'
... 4 levels...
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:43:in parse_key_item' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:20:inblock in parse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:19:in times' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/descriptor.rb:19:inparse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer_info/placed_layer.rb:11:in parse' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer.rb:314:inblock in parse_extra_data'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer.rb:310:in each' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer.rb:310:inparse_extra_data'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer.rb:69:in parse' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer_mask.rb:53:inblock in parse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:in times' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd/layer_mask.rb:52:inparse'
from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd.rb:90:in layer_mask' from /Users/bfoz/.rvm/gems/ruby-1.9.3-p448/gems/psd-0.3.3/lib/psd.rb:54:inparse!'
from (irb):20
from /Users/bfoz/.rvm/rubies/ruby-1.9.3-p448/bin/irb:16:in `

'>>
?> pp psd.tree.to_hash
{:children=>[], :document=>{:width=>640, :height=>960}}
{
:children => [],
:document => {
:width => 640,
:height => 960
}
}

Extract guides?

Is there any way to retrieve any information on a documents guides?

Bugs when trying to parse image data

When I parse a .psd file's layer as an image, I get an issue.
Example:
psd = PSD.new("test.psd")
psd.tree.children.first.image.parse
NoMethodError: undefined method unpack' for nil:NilClass from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/file.rb:44:inblock (2 levels) in class:File'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/image_formats/layer_rle.rb:10:in block in parse_byte_counts!' from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/image_formats/layer_rle.rb:9:intimes'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/image_formats/layer_rle.rb:9:in parse_byte_counts!' from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/image_formats/rle.rb:8:inparse_rle!'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/channel_image.rb:87:in parse_image_data!' from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/channel_image.rb:61:inblock in parse'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/channel_image.rb:42:in each' from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/channel_image.rb:42:inparse'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/lazy_execute.rb:54:in load!' from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/lazy_execute.rb:39:inmethod_missing'
from /Users/michaeleisel/.rvm/gems/ruby-2.1.0/gems/psd-1.5.0/lib/psd/nodes/build_preview.rb:9:in to_png' from (irb):117 from /Users/michaeleisel/.rvm/rubies/ruby-2.1.0/bin/irb:11:in

'

I'm using Ruby 2.1.0 and Rails 4.0.2. What might be the issue?

DL link to the .psd file I was using: http://speedy.sh/gNgnd/test.psd

Invalid argument (Errno::EINVAL) error in layer_mask.rb

require 'psd'
PSD.debug = true
f = PSD.new('my_file.psd')
f.parse!

give such an error:

...many lines of debug info...
DEBUG: SKIPPING: key = lyvr, length = 4
DEBUG: Layer name = krok 1
DEBUG: Layer Info: key = luni, start = 2887970, length = 40
DEBUG: Layer Info: key = lyid, start = 2888022, length = 4
DEBUG: Layer Info: key = lsct, start = 2888038, length = 16
DEBUG: SKIPPING: key = lspf, length = 4
DEBUG: SKIPPING: key = lclr, length = 8
DEBUG: SKIPPING: key = shmd, length = 1120
DEBUG: Layer Info: key = fxrp, start = 2889234, length = 16
DEBUG: Layer name = popup dodawanie C
DEBUG: Global Mask: length = -2113957377
DEBUG: {:overlay_color_space=>-32257, :color_components=>[-127, -111, -127, -127], :opacity=>-28161, :kind=>129}
Errno::EINVAL: Invalid argument - my_file.psd
    from ~/.rvm/gems/ruby-1.9.3-p392/gems/psd-0.4.1/lib/psd/layer_mask.rb:126:in `seek'
    from ~/.rvm/gems/ruby-1.9.3-p392/gems/psd-0.4.1/lib/psd/layer_mask.rb:126:in `parse_global_mask'
    from ~/.rvm/gems/ruby-1.9.3-p392/gems/psd-0.4.1/lib/psd/layer_mask.rb:67:in `parse'
    from ~/.rvm/gems/ruby-1.9.3-p392/gems/psd-0.4.1/lib/psd.rb:115:in `layer_mask'
    from ~/.rvm/gems/ruby-1.9.3-p392/gems/psd-0.4.1/lib/psd.rb:74:in `parse!'
    from (irb):9
    from ~/.rvm/rubies/ruby-1.9.3-p392/bin/irb:16:in `<main>'

As you can see, I'm using ruby 1.9.3-p392. Sadly I can't share with you this psd file, couse my work policy.

Parse and apply group mask when building previews

Groups can have masks too. With the incorrect optimization gone, this no longer breaks parsing. However, when building a preview, the group mask is never applied nor parsed properly.

The channels for a group with a mask look like this:

[
  {:id=>-1, :length=>2}, 
  {:id=>0, :length=>2}, 
  {:id=>1, :length=>2}, 
  {:id=>2, :length=>2}, 
  {:id=>-2, :length=>44438}
]

Each channel is only 2 bytes except for the mask channel, which contains data and assumes the size of the layer mask.

Non English character in text layer

I'v got strange sequence of symbols while parsing text value of psd text layer with russian language. For example word "ะšะพะฝั‚ะฐะบั‚ั‹" is represented as "\u0004\u001A\u0004>\u0004=\u0004B\u00040\u0004:\u0004B\u0004K\n"
It seems like this is encoding problem because the code of letter K should be "041A" and here we have "\u0004\u001A" I was digging PSD.TypeTool.parse and PSD.File.read_unicode_string but can`t get it work.

Current or "active" font in text layer

Hello guys

I'm trying to parse a text layer in order to retrieve the "active" font .

Somehow the psd saves a history of the types used on the layer.

I've checked the ResourceDict.FontSet from the engine data and i have this

screen shot 2013-10-22 at 2 59 27 am

All the layer's text is in Verdana, but Verdana its on the 2nd position of the array. How can i know which array element its the active?

Or maybe how can i clean all the fonts but the active font name?

Regards!

ChunkyPNG::Color.greyscale/grayscale

psd.rb seems to call ChunkyPNG::Color.greyscale (with an 'e') (https://github.com/layervault/psd.rb/blob/master/lib/psd/image_modes/greyscale.rb#L16), but the method seems to be called ChunkyPNG::Color.grayscale (with an 'a') (https://github.com/wvanbergen/chunky_png/blob/chunky_png-1.2.7/lib/chunky_png/color.rb#L108).

I've looked through blame it seems to have always been this case, in both repos. Any idea why this is? I can't find any alias - so how is this working?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.