上面已经把图层的信息都已经拿到了,剩下的byteArray就是图片的通道数据,这里就根据它的通道长度信息来获取对应的值,从而组合成对应的像素生成图片。
Channel Image data一共包含两个部分:
Compression是图片的压缩格式,0是原始数据,未经过任何处理的,1是使用了RLE压缩格式。
这里只处理RLE压缩格式的情况:
for (i = 0; i < layerCount; i++)
{
layerVo = layerVect[i];
layerVo.parsePixel(layerData);
}
public function parsePixel(ba:ByteArray):void
{
var tempObj:Object;
//RGBA通道数据数组,前面已经获取过每种通道的长度信息
for (var i:int = 0; i < channelDataArr.length; i++)
{
tempObj = channelDataArr[i];
tempObj.compressedType = ba.readUnsignedShort();
var pixelDataByte:ByteArray = new ByteArray();
//If the Layer’s Size, and therefore the data, is odd, a pad byte will be inserted at the end of the row.
//放弃最后两个字节
if (tempObj.channelLen - 2 > 1)
{
ba.readBytes(pixelDataByte, 0, tempObj.channelLen - 2);
}
tempObj.pixelData = getRealPixelData(tempObj.compressedType, pixelDataByte);
}
}
private function getRealPixelData(compress:int, data:ByteArray):ByteArray
{
if(1 == compress)
{
//使用height是因为它是按照行来压缩的
return decodeRLE(data, height);
}
return data;
}
//解压缩
public function decodeRLE(source : ByteArray, height : int) : ByteArray
{
source.position = 0;
var lines : Array = new Array(height);
var i : int = 0;
var total : int;
var size : int;
for ( i = 0; i < height; ++i ) {
size = source.readUnsignedShort();
lines[i] = size;
total += lines[i];
}
if (source.position + total != source.length) {
throw new Error("rle decode error");
}
var target : ByteArray = new ByteArray();
var length : int = 0;
var j : int;
var k : int;
var n : int;
var count : int;
for ( i = 0; i < height; ++i ) {
length = lines[i];
j = 0;
count = 0;
while (j < length) {
n = source.readByte();
j++;
if (n >= 0) {
count = n + 1;
for (k = 0;k < count;++k) {
target.writeByte(source.readByte());
}
j += count;
} else {
count = 1 - n;
var byte : int = source.readByte();
for (k = 0;k < count;++k) {
target.writeByte(byte);
}
j++;
}
}
}
return target;
}
根据得到的每种颜色的值进行计算得到对应的像素值:
private static function createPic(layerVo:LayerVo):void
{
if(true == layerVo.isFolder || true == layerVo.isText) return;
var color:uint;
var alphaChannel:ByteArray = (layerVo.channelDataArr[0].pixelData as ByteArray);
var redChannel:ByteArray = (layerVo.channelDataArr[1].pixelData as ByteArray);
var greenChannel:ByteArray = (layerVo.channelDataArr[2].pixelData as ByteArray);
var blueChannel:ByteArray = (layerVo.channelDataArr[3].pixelData as ByteArray);
alphaChannel.position = redChannel.position = greenChannel.position = blueChannel.position = 0;
var bmd:BitmapData = new BitmapData(layerVo.width, layerVo.height);
bmd.lock();
//逐个像素计算颜色值
for (var h:int = 0; h < layerVo.height; h++)
{
for (var w:int = 0; w < layerVo.width; w++)
{
var alpha:uint = alphaChannel.readUnsignedByte();
var red:uint = redChannel.readUnsignedByte();
var green:uint = greenChannel.readUnsignedByte();
var blue:uint = blueChannel.readUnsignedByte();
color = alpha << 24 |red << 16 |green << 8 | blue;
bmd.setPixel32(w, h, color);
}
}
bmd.unlock();
var url:String = File.desktopDirectory.nativePath + "/image/" + layerVo.layerName+".png";
//生成图片
FileUtil.createPng(url, bmd);
}
这个东西讲的有点乱,直接发个整理过的xmind给需要的同学,自己跟着去研究吧:
http://pan.baidu.com/s/1ge8Dnnd
代码的路径,只是做了简单的psd解析成vo,剩下的根据自己的实际需求改呗:
http://pan.baidu.com/s/1i513hHz