Commit b4361e14 authored by Ryan LeFevre's avatar Ryan LeFevre

Merge branch 'channel_images'

parents 8be456c8 539ca415
The MIT License (MIT)
Copyright (c) 2014 Ryan LeFevre
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This diff is collapsed.
var PSD = require('../../');
var file = process.argv[2] || './examples/images/example.psd';
var start = new Date();
PSD.open(file).then(function (psd) {
psd.tree().descendants().forEach(function (node) {
if (node.isGroup()) return true;
node.saveAsPng("./output/" + node.name + ".png").catch(function (err) {
console.log(err.stack);
});
});
}).then(function () {
console.log("Finished in " + ((new Date()) - start) + "ms");
}).catch(function (err) {
console.log(err.stack);
});
_ = require 'lodash'
Image = require './image.coffee'
ImageFormat = require './image_format.coffee'
module.exports = class ChannelImage extends Image
@includes ImageFormat.LayerRAW
@includes ImageFormat.LayerRLE
constructor: (file, header, @layer) ->
@_width = @layer.width
@_height = @layer.height
super(file, header)
@channelsInfo = @layer.channelsInfo
@hasMask = _.any @channelsInfo, (c) -> c.id < -1
@opacity = @layer.opacity / 255.0
@maskData = []
skip: ->
for chan in @channelsInfo
@file.seek chan.length, true
width: -> @_width
height: -> @_height
channels: -> @layer.channels
parse: ->
@chanPos = 0
for chan in @channelsInfo
if chan.length <= 0
@parseCompression()
continue
@chan = chan
if chan.id < -1
@_width = @layer.mask.width
@_height = @layer.mask.height
else
@_width = @layer.width
@_height = @layer.height
@length = @_width * @_height
start = @file.tell()
@parseImageData()
finish = @file.tell()
if finish isnt start + @chan.length
@file.seek(start + @chan.length)
@_width = @layer.width
@_height = @layer.height
@processImageData()
parseImageData: ->
@compression = @parseCompression()
switch @compression
when 0 then @parseRaw()
when 1 then @parseRLE()
when 2, 3 then @parseZip()
else @file.seek(@endPos)
...@@ -77,4 +77,4 @@ module.exports = class Image extends Module ...@@ -77,4 +77,4 @@ module.exports = class Image extends Module
when 3 then @combineRgbChannel() when 3 then @combineRgbChannel()
when 4 then @combineCmykChannel() when 4 then @combineCmykChannel()
@channelData = null @channelData = null
\ No newline at end of file
module.exports = module.exports =
RAW: require('./image_formats/raw.coffee') RAW: require('./image_formats/raw.coffee')
RLE: require('./image_formats/rle.coffee') RLE: require('./image_formats/rle.coffee')
\ No newline at end of file LayerRLE: require('./image_formats/layer_rle.coffee')
LayerRAW: require('./image_formats/layer_raw.coffee')
module.exports =
parseRaw: ->
for i in [@chanPos...(@chanPos + @chan.length - 2)]
@channelData[i] = @file.readByte()
@chanPos += (@chan.length - 2)
module.exports =
parseByteCounts: ->
@file.readShort() for i in [0...@height()]
parseChannelData: ->
@lineIndex = 0
@decodeRLEChannel()
...@@ -8,7 +8,7 @@ module.exports = class Layer extends Module ...@@ -8,7 +8,7 @@ module.exports = class Layer extends Module
@includes require('./layer/name.coffee') @includes require('./layer/name.coffee')
@includes require('./layer/info.coffee') @includes require('./layer/info.coffee')
@includes require('./layer/helpers.coffee') @includes require('./layer/helpers.coffee')
# @includes require('./layer/channel_image.coffee') @includes require('./layer/channel_image.coffee')
constructor: (@file, @header) -> constructor: (@file, @header) ->
@mask = {} @mask = {}
...@@ -53,4 +53,4 @@ module.exports = class Layer extends Module ...@@ -53,4 +53,4 @@ module.exports = class Layer extends Module
opacity: @opacity opacity: @opacity
visible: @visible visible: @visible
clipped: @clipped clipped: @clipped
mask: @mask.export() mask: @mask.export()
\ No newline at end of file
ChannelImage = require '../channel_image.coffee'
LazyExecute = require '../lazy_execute.coffee'
module.exports =
parseChannelImage: ->
image = new ChannelImage(@file, @header, @)
@image = new LazyExecute(image, @file)
.now('skip')
.later('parse')
.get()
...@@ -36,6 +36,8 @@ module.exports = class LayerMask ...@@ -36,6 +36,8 @@ module.exports = class LayerMask
for i in [0...layerCount] for i in [0...layerCount]
@layers.push new Layer(@file, @header).parse() @layers.push new Layer(@file, @header).parse()
layer.parseChannelImage() for layer in @layers
parseGlobalMask: -> parseGlobalMask: ->
length = @file.readInt() length = @file.readInt()
return if length <= 0 return if length <= 0
...@@ -56,4 +58,4 @@ module.exports = class LayerMask ...@@ -56,4 +58,4 @@ module.exports = class LayerMask
# 0 = color selected, 1 = color protected, 128 = use value per layer # 0 = color selected, 1 = color protected, 128 = use value per layer
mask.kind = @file.readByte() mask.kind = @file.readByte()
@file.seek maskEnd @file.seek maskEnd
\ No newline at end of file
...@@ -4,6 +4,7 @@ _ = require 'lodash' ...@@ -4,6 +4,7 @@ _ = require 'lodash'
module.exports = class Node extends Module module.exports = class Node extends Module
@includes require('./nodes/ancestry.coffee') @includes require('./nodes/ancestry.coffee')
@includes require('./nodes/search.coffee') @includes require('./nodes/search.coffee')
@includes require('./nodes/build_preview.coffee')
@PROPERTIES: ['name', 'left', 'right', 'top', 'bottom', 'height', 'width'] @PROPERTIES: ['name', 'left', 'right', 'top', 'bottom', 'height', 'width']
...@@ -93,4 +94,4 @@ module.exports = class Node extends Module ...@@ -93,4 +94,4 @@ module.exports = class Node extends Module
@left = _.min(nonEmptyChildren.map((c) -> c.left)) or 0 @left = _.min(nonEmptyChildren.map((c) -> c.left)) or 0
@top = _.min(nonEmptyChildren.map((c) -> c.top)) or 0 @top = _.min(nonEmptyChildren.map((c) -> c.top)) or 0
@bottom = _.max(nonEmptyChildren.map((c) -> c.bottom)) or 0 @bottom = _.max(nonEmptyChildren.map((c) -> c.bottom)) or 0
@right = _.max(nonEmptyChildren.map((c) -> c.right)) or 0 @right = _.max(nonEmptyChildren.map((c) -> c.right)) or 0
\ No newline at end of file
module.exports =
toPng: -> @layer.image.toPng()
saveAsPng: (output) -> @layer.image.saveAsPng(output)
...@@ -13,4 +13,4 @@ module.exports = class Group extends Node ...@@ -13,4 +13,4 @@ module.exports = class Group extends Node
export: -> export: ->
_.merge super(), _.merge super(),
type: 'group' type: 'group'
children: @_children.map((c) -> c.export()) children: @_children.map((c) -> c.export())
\ No newline at end of file
...@@ -10,4 +10,4 @@ module.exports = class Layer extends Node ...@@ -10,4 +10,4 @@ module.exports = class Layer extends Node
_.merge super, _.merge super,
type: 'layer' type: 'layer'
mask: @layer.mask.export() mask: @layer.mask.export()
image: {} image: {}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment