public void LoadImage(String strUrl) {
        DataInputStream inputDate = null;
        try {
            inputDate = new DataInputStream(new FileInputStream(strUrl));
            System.out.println(inputDate.available());
            inputDate.skipBytes(8);  //跳过文件头
            /**IHDR数据块**/
            inputDate.skipBytes(4);  //Chunk length
            inputDate.skipBytes(4);  //0x49484452为Chunk Type "IHDR"
            m_width = inputDate.readInt();   //宽度
            m_height = inputDate.readInt();  //高度
            m_depth = inputDate.readByte();  //位深度
            inputDate.skipBytes(4);  //压缩时舍掉的4byte,默认0x03000000
            inputDate.skipBytes(4);  //跳过IHDR文件CRC信息
            SkipDate(inputDate,3);   //跳过3个数据块
            m_PLTE = SaveDate(inputDate);  //保存PLTE数据块
            SkipDate(inputDate, 6);  //跳过6个数据块
            m_IDAT = SaveDate(inputDate);  //保存IDAT数据块
            inputDate.close();
        } catch (Exception ex) {
            System.out.println("错误读入" + ex);
        }
    }    /**保存当前数据块**/
    private byte[] SaveDate(DataInputStream inputDate) throws IOException {
        //跳过3个数据块
        int tmplength = inputDate.readInt();   //读取Chunk length
        System.out.println("*******************保存数据块*******************"+tmplength);
        inputDate.skipBytes(4); //跳过数据块Chunk Type Code
        byte[] tmparray = new byte[tmplength];
        for (int i = 0; i < tmparray.length; ++i) {
            tmparray[i] = inputDate.readByte(); //位深度
        }
        inputDate.skipBytes(4); //跳过IHDR文件CRC信息
        return tmparray;
    }    /**跳过指定数量的数据块**/
    private void SkipDate(DataInputStream inputDate, int num) throws IOException {
        System.out.println("============跳过数据=============="+num);
        for (int i = num; i > 0; --i) {      //cHRM  基色和白色点数据块
            int tmplength = inputDate.readInt(); //cHRM信息length
            System.out.println(tmplength);
            inputDate.skipBytes(8 + tmplength); //跳过IHDR文件CRC信息]
            System.out.println(i);
        }
    }
//以上是我写的提取有效数据的代码,但是每次运行之后,读取宽度和高度是正确的,但是从保存第一个数据块开始就由于数组过大,把后面的数据全部读取完毕了,所以后面的关键数据块没有数据可以读取了!
读取的数据块排列顺序是下面这个表

解决方案 »

  1.   

    没用过ImageIO,我是想提取出png图片里面的关键信息,然后把重复或者不关键的信息去掉,保存成新的二进制文件,下次读取的时候,再还原成完整PNG,这样可以压缩掉大量的空间,对J2ME手机游戏开发很有帮助!
      

  2.   

    有没有试过强大的Imageick,命令行的,有针对各主流语言的接口。比如JMagick
      

  3.   

    Google和百度都是首选嘛,正常人都会这么做!鄙视!
      

  4.   

    你去他官网上查一下啊。compress -quality 50% old.png new.png对你帮助不大
      

  5.   

    你直接把inputDate 中的全部数据放到一个 byte[] 中,然后通过下标操作这个byte[]呗。直接在 byte[]中查找PLTE IDAT IEND的 ASSIC码 直接能找到块的位置吧。读长度什么的inputDate.readInt()和inputDate.readbyte()无非就是下标走的步长不一样。
      

  6.   

    inputDate.readInt()读取长度会出现失误?
      

  7.   

    OK,http://opensource.csdn.net/bbs/thread/4373convert -strip old.png new.png如果可能,加上-quality n% 在-strip后,控制质量。我测试了一个100x100的png,在没有改变质量的前提下,从5.58k -> 3.39k
      

  8.   

    上面的是命令行的,JavaAPI怎么掉不清楚。BTW,项目名打错了,应该是ImageMagick,对应的JavaAPI叫JMagick。另外,请注意这些项目的开源协议分别是GPL和LGPL的。
      

  9.   

    名称  字节数  说明  
    Length (长度)  4字节  指定数据块中数据域的长度,其长度不超过(231-1)字节  
    Chunk Type Code (数据块类型码)  4字节  数据块类型码由ASCII字母(A-Z和a-z)组成  
    Chunk Data (数据块数据)  可变长度  存储按照Chunk Type Code指定的数据  
    CRC (循环冗余检测)  4字节  存储用来检测是否有错误的循环冗余码  
    我也没看太明白,那个Length 是Chunk Data 的长度还是 这4个东西的总和得实验下要是总和的话可以直接用,不是的话还得+上另外3个4字节吧
      

  10.   


    关于压缩部分——不用重复发明轮子。你要做的事情,现成的API已经搞定了。加密,不是很理解,在png文件内部压缩吗?读取这个文件的就只能你自己的程序了。
      

  11.   

    这个我测试过,头文件数据块第一个保存的length就是数据域Chunk Data 的长度,不包括其他部分
      

  12.   

    PNG文件数据块的结构
    名称 字节数 说明
    Length(长度) 4字节 指定数据块中数据域的长度,其长度不超过
    (231-1)字节
    Chunk Type Code(数据块类型码) 4字节 数据块类型码由ASCII字母(A-Z和a-z)组成
    Chunk Data(数据块数据) 可变长度 存储按照Chunk Type Code指定的数据
    CRC(循环冗余检测) 4字节 存储用来检测是否有错误的循环冗余码
    Chunk Data(数据块数据)的长度,我的理解是Length(长度)里面保存的长度!
    按这个理解
     int tmplength = inputDate.readInt(); //cHRM信息length
      System.out.println(tmplength);
      inputDate.skipBytes(8 + tmplength); //跳过IHDR文件CRC信息]
    这个语句应该可以跳过一个数据块的吧!跳过数据块貌似也是正常的!
    从这里开始
    int tmplength = inputDate.readInt(); //读取Chunk length
      System.out.println("*******************保存数据块*******************"+tmplength);
      inputDate.skipBytes(4); //跳过数据块Chunk Type Code
      byte[] tmparray = new byte[tmplength];
      for (int i = 0; i < tmparray.length; ++i) {
      tmparray[i] = inputDate.readByte(); //位深度
      }
      inputDate.skipBytes(4); //跳过IHDR文件CRC信息
    我是先保存这个当前数据块长度,然后跳过Chunk Type Code4个字节
    然后再读取数据域的数据for;最后再跳过CRC数据4个字节,问题貌似就出在这里,第一次读取的length大的离谱,所以导致后面没有数据可以读取了!
      

  13.   

    IHDR文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。文件头数据块由13字节组成,它的格式如下表所示。域的名称  字节数  说明  
    Width  4 bytes  图像宽度,以像素为单位  
    Height  4 bytes  图像高度,以像素为单位  
    Bit depth  1 byte  图像深度: 
    索引彩色图像:1,2,4或8 
    灰度图像:1,2,4,8或16 
    真彩色图像:8或16  
    ColorType  1 byte  颜色类型:
    0:灰度图像, 1,2,4,8或16 
    2:真彩色图像,8或16 
    3:索引彩色图像,1,2,4或8 
    4:带α通道数据的灰度图像,8或16 
    6:带α通道数据的真彩色图像,8或16  
    Compression method  1 byte  压缩方法(LZ77派生算法)  
    Filter method  1 byte  滤波器方法  
    Interlace method  1 byte  隔行扫描方法:
    0:非隔行扫描 
    1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法)  IHDR是13字节,你跳了15。http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=232
    参考下
      

  14.   

     /**IHDR数据块**/
      inputDate.skipBytes(4); //Chunk length
      inputDate.skipBytes(4); //0x49484452为Chunk Type "IHDR"
      m_width = inputDate.readInt(); //宽度
      m_height = inputDate.readInt(); //高度
      m_depth = inputDate.readByte(); //位深度
      inputDate.skipBytes(4); //压缩时舍掉的4byte,默认0x03000000
      inputDate.skipBytes(4); //跳过IHDR文件CRC信息
    4个4 =16。
      

  15.   

      m_width = inputDate.readInt(); //宽度  4byte
      m_height = inputDate.readInt(); //高度  4byte
      m_depth = inputDate.readByte(); //位深度  1byte
      inputDate.skipBytes(4); //压缩时舍掉的4byte,默认0x03000000   4byte
    13个啊,哪里跳过了15个?请指教
      

  16.   

    public class test {
    public void read() throws Exception{

     DataInputStream inputDate = new DataInputStream(new FileInputStream("d:\\1.png"));
     byte[] bytes=new byte[inputDate.available()];
     inputDate.read(bytes);
     byte[] IDATbyte ="IDAT".getBytes();
     byte[] IENDbyte ="IEND".getBytes();  int sgin = 0;//查找标志
     
     sgin = find(bytes,IDATbyte,0);//查找第一个IDAT块标志
     int IDATStrar = sgin-4;//向前4位,为第一个IDAT块的起始位置
     
     int temp = sgin;
    do{
    sgin = temp;
    temp = find(bytes,IDATbyte,sgin+4);//向前4为跳过"IDAT"
    }while(temp!=-1);//IDAT块为连续块,直接查找到最后一个IDAT int IDATDataLength = ((bytes[sgin-4]&0x000000ff)<<24)|((bytes[sgin-4+1]&0x000000ff)<<16)|((bytes[sgin-4+2]&0x000000ff)<<8)|(bytes[sgin-4+3]&0x000000ff);//byte转int
    int IDATEnd =sgin +3 + IDATDataLength +4;//数据块的结构  +3是因为sgin指向"IDAT"的I了

    sgin =  find(bytes,IENDbyte,IDATEnd);//IEND块在IDAT后
    int IENDStrar = sgin-4;//向前4位,为IEND块的起始位置
    int IENDDataLength = ((bytes[sgin-4]&0x000000ff)<<24)|((bytes[sgin-4+1]&0x000000ff)<<16)|((bytes[sgin-4+2]&0x000000ff)<<8)|(bytes[sgin-4+3]&0x000000ff);//byte转int
    int IENDEnd =sgin +3 + IENDDataLength +4;//数据块的结构 +3是因为sgin指向"IEND"的I了

    System.out.println("IDAT在bytes中的位置为bytes["+IDATStrar+"]-bytes["+IDATEnd+"]");
    System.out.println("IEND在bytes中的位置为bytes["+IENDStrar+"]-bytes["+IENDEnd+"]");

    }
    /**
     * 在bytes 中查找 findbytes
     * @param bytes (byte[])     目标
     * @param findbytes (byte[]) 查找条件
     * @param start (int)        查找起始位置实
     * @return int bytes中findbytes的起始位置
     */
    private int find( byte[] bytes,byte[] findbytes,int start){

    if(bytes!=null && bytes.length>0 && findbytes!=null && findbytes.length>0 &&  bytes.length>start && start>=0){

    for(int i = start;i<bytes.length;i++){

    for(int j = 0;j<findbytes.length;j++){

    if(bytes[i+j] != findbytes[j]){//不符合直接break
    break;
    }else{
    if(j == findbytes.length-1){//完全符合findbytes中的字符

    return i;//返回字符起始位置
    }
    }
    }

    }
    }

    return -1;//没查到
    }
    public static void main(String args[]){

    try {
    new test().read();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    }
    我用byte[]做的,你实验下吧,流做的那个我也找不到原因。
      

  17.   

    这位仁兄,我给你简单解释一下吧,不然你睡不着觉!
    这么做的目的是PNG文件厘米有很多信息是就算不同图片也是雷同的,所有就可以砍掉,从这个角度是压缩了PNG原始文件,从而节省出手机游戏开发时那珍贵的byte,砍掉这些数据的同时已经算是简单的加密了!一般人是不会把你的图片解码出来,然而为了真正的加密,就需要混淆真实数据等等!这样在内部范围内,就有了自己的加密手段!
      

  18.   

     public void LoadImage(String strUrl) {
            DataInputStream inputDate = null;
            try {
                inputDate = new DataInputStream(new FileInputStream(strUrl));
                int length = 0;
                System.out.println(length = inputDate.available());
                pngByteArray = new byte[length];
                inputDate.read(pngByteArray);
                String tmpstr="";
                byte[] tmparraycHRM = "cHRM".getBytes();
                byte[] tmparraygAMA = "gAMA".getBytes();
                byte[] tmparraycsBIT = "sBIT".getBytes();
                byte[] tmparrayIHDR = "IHDR".getBytes();
                byte[] tmparrayPLTE = "PLTE".getBytes();
                 byte[] tmparrayIDAT = "IDAT".getBytes();            int a = 0;
                if ((a = FindData(tmparrayIHDR)) != -1) {
                    System.out.println("IHDR数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("IHDR没有出现");
                }
                if ((a = FindData(tmparraycHRM)) != -1) {
                    System.out.println("cHRM数据块出现位置" + (a - 4));
                 } else {
                    System.out.println("cHRM没有出现");
                }
                if ((a = FindData(tmparraygAMA)) != -1) {
                    System.out.println("gAMA数据块出现位置" + (a - 4));
                 } else {
                    System.out.println("gAMA没有出现");
                }
                if ((a = FindData(tmparraycsBIT)) != -1) {
                    System.out.println("sBIT数据块出现位置" + (a - 4));
                 } else {
                    System.out.println("sBIT没有出现");
                }
                if ((a = FindData(tmparrayPLTE)) != -1) {
                    System.out.println("PLTE数据块出现位置" + (a - 4));
                 } else {
                    System.out.println("PLTER没有出现");
                }
                 if ((a = FindData(tmparrayIDAT)) != -1) {
                    System.out.println("IDAT数据块出现位置" + (a - 4));
                 } else {
                    System.out.println("IDAT没有出现");
                }
                inputDate.close();
            } catch (Exception ex) {
                System.out.println("错误读入" + ex);
            }
        }
    验证结果:
    83423
    IHDR数据块出现位置8
    cHRM数据块出现位置2705
    gAMA没有出现
    sBIT没有出现
    PLTER没有出现
    IDAT数据块出现位置2749
    /------------------数据块表---------------------/
    数据块符号 数据块名称 多数据块 可选否 位置限制
    IHDR 文件头数据块 否 否 第一块
    cHRM 基色和白色点数据块 否 是 在PLTE和IDAT之前
    gAMA 图像γ数据块 否 是 在PLTE和IDAT之前
    sBIT 样本有效位数据块 否 是 在PLTE和IDAT之前
    PLTE 调色板数据块 否 是 在IDAT之前
    bKGD 背景颜色数据块 否 是 在PLTE之后IDAT之前
    hIST 图像直方图数据块 否 是 在PLTE之后IDAT之前
    tRNS 图像透明数据块 否 是 在PLTE之后IDAT之前
    oFFs (专用公共数据块) 否 是 在IDAT之前
    pHYs 物理像素尺寸数据块 否 是 在IDAT之前
    sCAL (专用公共数据块) 否 是 在IDAT之前
    IDAT 图像数据块 是 否 与其他IDAT连续
    tIME 图像最后修改时间数据块 否 是 无限制
    tEXt 文本信息数据块 是 是 无限制
    zTXt 压缩文本数据块 是 是 无限制
    fRAc (专用公共数据块) 是 是 无限制
    gIFg (专用公共数据块) 是 是 无限制
    gIFt (专用公共数据块) 是 是 无限制
    gIFx (专用公共数据块) 是 是 无限制
    IEND 图像结束数据 否 否 最后一个数据块
    /:验证发现,验证结果是,真实PNG图片于此表不符!
      

  19.   

    恩,这个表应该是最复杂的png,最简单的png只有头8个字节+IHDR、IDAT和IEND。处理的时候直接查找块比较安全。
      

  20.   

    最后和大家分享一下,为什么不能用流直接跳过处理的原因!
    /------------------数据块表---------------------/
    数据块符号 数据块名称 多数据块 可选否 位置限制
    IHDR 文件头数据块 否 否 第一块
    cHRM 基色和白色点数据块 否 是 在PLTE和IDAT之前
    gAMA 图像γ数据块 否 是 在PLTE和IDAT之前
    sBIT 样本有效位数据块 否 是 在PLTE和IDAT之前
    PLTE 调色板数据块 否 是 在IDAT之前
    bKGD 背景颜色数据块 否 是 在PLTE之后IDAT之前
    hIST 图像直方图数据块 否 是 在PLTE之后IDAT之前
    tRNS 图像透明数据块 否 是 在PLTE之后IDAT之前
    oFFs (专用公共数据块) 否 是 在IDAT之前
    pHYs 物理像素尺寸数据块 否 是 在IDAT之前
    sCAL (专用公共数据块) 否 是 在IDAT之前
    IDAT 图像数据块 是 否 与其他IDAT连续
    tIME 图像最后修改时间数据块 否 是 无限制
    tEXt 文本信息数据块 是 是 无限制
    zTXt 压缩文本数据块 是 是 无限制
    fRAc (专用公共数据块) 是 是 无限制
    gIFg (专用公共数据块) 是 是 无限制
    gIFt (专用公共数据块) 是 是 无限制
    gIFx (专用公共数据块) 是 是 无限制
    IEND 图像结束数据 否 否 最后一个数据块
    /:仔细观察这个表就发现,表内其实有一部分数据块的位置没有限制,这就导致,你所遇到的PNG图片,你根本不知道,在PLTE或者IDAT之前到底有几个数据块,或者根本就没有PLTE,所以导致按照表跳过数据会失败的一塌糊涂!
    werosh  非常感谢你的启发和帮助
    以下是我验证的代码和结果:
    public void ReadImage(String strUrl) {
            DataInputStream inputDate = null;
            try {
                inputDate = new DataInputStream(new FileInputStream(strUrl));
                int length = 0;
                System.out.println(length = inputDate.available());
                pngByteArray = new byte[length];
                inputDate.read(pngByteArray);
                String tmpstr = "";
                byte[] tmparraycHRM = "cHRM".getBytes();
                byte[] tmparraygAMA = "gAMA".getBytes();
                byte[] tmparraycsBIT = "sBIT".getBytes();
                byte[] tmparrayIHDR = "IHDR".getBytes();
                byte[] tmparrayPLTE = "PLTE".getBytes();
                byte[] tmparrayIDAT = "IDAT".getBytes();
                byte[] tmparrayIEND = "IEND".getBytes();
                byte[] tmparraygIFx = "gIFx".getBytes();
                byte[] tmparraycgIFt = "gIFt".getBytes();
                byte[] tmparraygIFg = "gIFg".getBytes();
                byte[] tmparrayfRAc = "fRAc".getBytes();
                byte[] tmparrayzTXt = "zTXt".getBytes();
                byte[] tmparraytEXt = "tEXt".getBytes();
                byte[] tmparraytIME = "tIME".getBytes();
                byte[] tmparraycsCAL = "sCAL".getBytes();
                byte[] tmparraypHYs = "pHYs".getBytes();
                byte[] tmparrayoFFs = "oFFs".getBytes();
                byte[] tmparraytRNS = "tRNS".getBytes();
                byte[] tmparrayhIST = "hIST".getBytes();
                byte[] tmparraybKGD = "bKGD".getBytes();
                int a = 0;
                if ((a = FindData(tmparrayIHDR)) != -1) {
                    System.out.println("IHDR数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("IHDR没有出现");
                }
                if ((a = FindData(tmparraypHYs)) != -1) {
                    System.out.println("pHYs数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("pHYs没有出现");
                }
                if ((a = FindData(tmparraycHRM)) != -1) {
                    System.out.println("cHRM数据块出现位置" + (a - 4));
                } else {
                    System.out.println("cHRM没有出现");
                }
                if ((a = FindData(tmparrayPLTE)) != -1) {
                    System.out.println("PLTE数据块出现位置" + (a - 4));
                } else {
                    System.out.println("PLTE没有出现");
                }
                if ((a = FindData(tmparrayIDAT)) != -1) {
                    System.out.println("IDAT数据块出现位置" + (a - 4));
                } else {
                    System.out.println("IDAT没有出现");
                }
                if ((a = FindData(tmparraycgIFt)) != -1) {
                    System.out.println("gIFt数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("gIFt没有出现");
                }
                if ((a = FindData(tmparraygIFx)) != -1) {
                    System.out.println("gIFx数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("gIFx没有出现");
                }
                if ((a = FindData(tmparrayIEND)) != -1) {
                    System.out.println("IEND数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("IEND没有出现");
                }
                //
                if ((a = FindData(tmparraytIME)) != -1) {
                    System.out.println("tIME数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("tIME没有出现");
                }
                if ((a = FindData(tmparraytEXt)) != -1) {
                    System.out.println("tEXt数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("tEXt没有出现");
                }
                if ((a = FindData(tmparrayzTXt)) != -1) {
                    System.out.println("zTXt数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("zTXt没有出现");
                }
                if ((a = FindData(tmparrayfRAc)) != -1) {
                    System.out.println("fRAc数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("fRAc没有出现");
                }
                if ((a = FindData(tmparraygIFg)) != -1) {
                    System.out.println("gIFg数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("gIFg没有出现");
                }
                //
                if ((a = FindData(tmparraybKGD)) != -1) {
                    System.out.println("bKGD数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("bKGD没有出现");
                }
                if ((a = FindData(tmparrayhIST)) != -1) {
                    System.out.println("hIST数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("hIST没有出现");
                }
                if ((a = FindData(tmparraytRNS)) != -1) {
                    System.out.println("tRNS数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("tRNS没有出现");
                }
                if ((a = FindData(tmparrayoFFs)) != -1) {
                    System.out.println("oFFs数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("oFFs没有出现");
                }            if ((a = FindData(tmparraycsCAL)) != -1) {
                    System.out.println("sCAL数据块出现位置" + (a - 4));
    //                System.out.println("IHDR数据块总长度" + (a - 4));
                } else {
                    System.out.println("sCAL没有出现");
                }            if ((a = FindData(tmparraygAMA)) != -1) {
                    System.out.println("gAMA数据块出现位置" + (a - 4));
                } else {
                    System.out.println("gAMA没有出现");
                }
                if ((a = FindData(tmparraycsBIT)) != -1) {
                    System.out.println("sBIT数据块出现位置" + (a - 4));
                } else {
                    System.out.println("sBIT没有出现");
                }
                inputDate.close();
            } catch (Exception ex) {
                System.out.println("错误读入" + ex);
            }
        }
    private int FindData(byte[] tmparray) {
            for (int i = 0; i < pngByteArray.length; ++i) {
                if (tmparray[0] == pngByteArray[i]) {
                    int j = 1;
                    for (j = 1; j < tmparray.length; ++j) {
                        if (tmparray[j] != pngByteArray[i + j]) {
                            break;
                        }
                    }
                    if (j == tmparray.length) {
                        return i;
                    }
                }
            }
            return -1;
        }
    //:结果
    IHDR数据块出现位置8
    pHYs没有出现
    cHRM没有出现
    PLTE数据块出现位置70
    IDAT数据块出现位置130
    gIFt没有出现
    gIFx没有出现
    IEND数据块出现位置659
    tIME没有出现
    tEXt数据块出现位置33
    zTXt没有出现
    fRAc没有出现
    gIFg没有出现
    bKGD没有出现
    hIST没有出现
    tRNS没有出现
    oFFs没有出现
    sCAL没有出现
    gAMA没有出现
    sBIT没有出现
    备注:用不同的PNG图片验证你会发现数据块数量和位置非常诡异!
      

  21.   

    werosh你可以去回复J2ME区的一个相同PNG的贴把那100分给你!