javaStruct - 通讯协议的解封包第三方库--(二)官方文档三

原文链接

https://code.google.com/archive/p/javastruct/wikis/example_photoshop_acb_file_reader_writer.wiki

翻译用工具

翻译使用的是个人免费版Transmate

译文

如何使用JavaStruct读写Adobe Photoshop Color book文件
JavaStruct对于读写特定的二进制文件也是非常理想的。在这个例子中,我们将写一个 Photoshop Color book 文件读写器。这种文件格式的细节可在这里找到。
完整的代码请到:http://javastruct.googlecode.com/svn/trunk/javastruct/samples/photoshop/
备注:我注意到使用一个nio ByteBuffer写这样一个读写器并不是非常困难(可能更短)。但是JavaStruct提供了更清晰,可维护性更好的代码。并且如果有许多的二进制文件或消息,处理解封包将是非常容易引入错误的。

文件头
在头部,有一个特定的字符串字段. ±-------±----------------------//----------------------------------------+ | Length | UTF-16 Characters \ | ±-------±----------------------//----------------------------------------+
这样首先我们需要将这些字符串用一个特别的结构类表示,姑且叫 A 结构体。我们使用数组长度标记来声明。

@StructClass 
public class AString { 
  @StructField (order = 0 ) 
  @ArrayLengthMarker (fieldName = "chars") 
  public int length; 

  @StructField (order = 1) 
  public char[] chars;

  public AString(String content){ 
    this.length = content.length(); 
    this.chars = content.toCharArray(); 
  } 
  ... 
}

下面是实际的头。

@StructClass 
public class ACBHeader { 
  public static final short RGB = 0; 
  public static final short CMYK = 2; 
  public static final short LAB = 7; 

  // 签名通常是ASCII字符串“8BCB"
  @StructField (order = 0) 
  public byte[] signature = {'8', 'B', 'C', 'B'}; 

  //Photoshop 7 仅打开版本为1(0x0001)的文件
  @StructField (order = 1) 
  public short fileVersion; 

  // 唯一识别符
  @StructField (order = 2) 
  public short colorBookIdentifier; 

  @StructField (order = 3) 
  public AString title; 

  @StructField (order = 4) 
  public AString colorNamePrefix; 

  @StructField (order = 5) 
  public AString colorNamePostfix; 

  // 通常是一个版权声明
  @StructField (order = 6) 
  public AString description; 

  @StructField (order = 7) 
  public short colorCount; 

  // Photoshop 每页显示颜色数.这个字段指定了
  // 能够在一个页面上显示的颜色的最大数量. 
  @StructField (order = 8) 
  public short colorsPerPage; 

  @StructField (order = 9) 
  public short pageSelectorOffset; 

  // RGB, CMYK or Lab 
  @StructField (order = 10) 
  public short colorSpaceID; 
  ... 

读取颜色
这里是比较棘手的部分。通过格式化,颜色值和它的格式是依赖于 colorSpaceID 字段。其可以是RGB,CMYK或者Lab。这样我们对每一个颜色域写一个类。这里有颜色数据的”colorCount"数量值。

@StructClass 
public class RGBColor{ 
  @StructField (order = 0) 
  public AString name; 

  @StructField (order = 1) 
  public byte[] code = new byte[6]; 

  @StructField (order = 2) 
  public byte red; 

  @StructField (order = 3) 
  public byte green; 

  @StructField (order = 4) 
  public byte blue; 
  ... 
} 

@StructClass 
public class LabColor { 
  @StructField (order = 0) 
  public AString name; 

  @StructField (order = 1) 
  public byte[] code = new byte[6]; 

  @StructField (order = 2) 
  public byte lightness; 

  @StructField (order = 3) 
  public byte aChrom; 

  @StructField (order = 4) 
  public byte bChrom; 
  ... 
} 

注意对于每个颜色类都包含名字和编码字段。这是必要的,因为当前结构体类并不是从一个结构体基类派生的。

读写器
为了读和写acb文件,我们初始化了包含FileStream的StructPacker和StructUnpacker类。之后,读文件头和颜色值就直截了当。

public class AdobeColorBook { 
  ACBHeader header;
  RGBColor[] rgbColors = null; 
  CMYKColor[] cmykColors = null; 
  LabColor[] labColors = null; 
  
  public void read(String acbFile){ 
    try { 
      FileInputStream fis = new FileInputStream(new File(acbFile)); 
      header = new ACBHeader(); 
      StructUnpacker up = JavaStruct.getUnpacker(fis, ByteOrder.BIG_ENDIAN); 
      up.readObject(header); 
      switch(header.ColorSpaceID){ 
        case ACBHeader.RGB : 
          rgbColors = new RGBColor[header.colorCount]; 
          for(int i=0; i<header.colorCount; i++){ 
            rgbColors[i] = new RGBColor(); 
            up.readObject(rgbColors[i]); 
          } 
      break; 
      
      case ACBHeader.CMYK : 
        cmykColors = new CMYKColor[header.colorCount]; 
        for(int i=0; i<header.colorCount; i++){ 
          cmykColors[i] = new CMYKColor(); 
          up.readObject(cmykColors[i]); 
        } 
      break; 
      
      case ACBHeader.LAB : 
        labColors = new LabColor[header.colorCount]; 
        for(int i=0; i<header.colorCount; i++){ 
          labColors[i] = new LabColor(); 
          up.readObject(labColors[i]); 
        } 
      break; 
      default: 
    } 
    } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
    } catch (StructException e) { 
      e.printStackTrace(); 
    } 
  } 

  public void write(String name){ 
    try{ 
      FileOutputStream fo = new FileOutputStream(new File(name)); 
      StructPacker packer = JavaStruct.getPacker(fo, ByteOrder.BIG_ENDIAN); 
      packer.writeObject(header); 
      switch(header.ColorSpaceID){ 
        case ACBHeader.RGB : 
          for(RGBColor color : rgbColors){ 
            packer.writeObject(color); 
          } 
        break; 
        case ACBHeader.CMYK : 
          for(CMYKColor color : cmykColors){ 
            packer.writeObject(color); 
          } 
        break; 
        case ACBHeader.LAB : 
          for(LabColor color : labColors){ 
            packer.writeObject(color); 
          } 
        break; 
        default: 
        } 
      fo.close(); 
      } catch(StructException e){ 
        e.printStackTrace(); 
      } catch (IOException e) { 
        e.printStackTrace(); 
      } 
    } 

  public String toString(){ 
    String str = ""; 
    if (header != null){ 
      str += header; 
    } 
    switch(header.ColorSpaceID){ 
      case ACBHeader.RGB : 
        for(RGBColor color : rgbColors) { 
          str += color + "\n"; 
        } 
      break; 
      case ACBHeader.CMYK : 
        for(CMYKColor color : cmykColors) { 
          str += color + "\n"; 
        } 
      break; 
      case ACBHeader.LAB : 
        for(LabColor color : labColors) { 
          str += color + "\n"; 
        } 
      break; 
    } 
    return str; 
  } 

  public static void main(String[] args) { 
    AdobeColorBook anpaBook = new AdobeColorBook(); 
    anpaBook.read("ANPA Color.acb"); 
    anpaBook.write("ANPA_my_Color.acb"); 
    System.out.println(anpaBook); 
  } 
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值