无法正确编码tiff文件,某些字符不是编码

时间:2016-07-17 05:12:44

标签: java encoding base64 tiff decoding

我有包含多个图像的TIFF文件,我需要循环遍历该TIFF文件以单独提取图像, 我使用了base64编码,然后使用substring分隔图像并使用base64解码在文件系统中写入,  但是只有一些图像能够提取。

示例:我在tiff文件中有7个图像,但它只提取了4个图像。

所以我已经将编码数据写入文件并读取,我只能看到II *编码字符为4个而不是7个... 当我使用记事本打开TIFF文件时,我可以看到7 II *。请告知,这是最好的方法。

我试图解码ecoded文件并且它是正确的,它有7个II *,但是在ecoded文件中我只能看到II *的4个编码(SUkq)值。

我无法使用下面的代码,因为我的TIFF文件包含II *之前的标题部分,在使用以下方法之前需要删除它。

 public void  doitJAI() throws IOException {
    FileSeekableStream ss = new FileSeekableStream("D:\\Users\\Vinoth\\workspace\\image.tif");
    ImageDecoder dec = ImageCodec.createImageDecoder("tiff", ss, null);
    int count = dec.getNumPages();
    TIFFEncodeParam param = new TIFFEncodeParam();
   param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);   
    param.setLittleEndian(false); // Intel
    System.out.println("This TIF has " + count + " image(s)");
    for (int i = 0; i < count; i++) {
        RenderedImage page = dec.decodeAsRenderedImage(i);
        File f = new File("D:\\Users\\Vinoth\\workspace\\single_" + i + ".tif");
        System.out.println("Saving " + f.getCanonicalPath());
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(page);
        pb.add(f.toString());
        pb.add("tiff");
        pb.add(param);
        RenderedOp r = JAI.create("filestore",pb);
        r.dispose();
    }
}

所以我使用下面的代码,这只是为了提取第一张图片。

public class SplitTIFFFile {

public static void main(String[] args) throws IOException {
    new SplitTIFFFile().doitJAI();
}

File file = new File("D:\\Users\\Vinoth\\workspace\\Testing\\image.tif");

    try {

                FileOutputStream imageOutFile;
                /*imageOutFile*/ try ( /*
                 * Reading a Image file from file system
                 */ FileInputStream imageInFile = new FileInputStream(file)) {
                    byte imageData[] = new byte[(int)file.length()];
                    imageInFile.read(imageData);
                    /*
                    * Converting Image byte array into Base64 String
                    */
                    String imageDataString = encodeImage(imageData);
                    String result = imageDataString.substring(imageDataString.indexOf("SUkq") , imageDataString.indexOf("SUkq"));
                    /*
                    * Converting a Base64 String into Image byte array
                    */
                    byte[] imageByteArray = decodeImage(result);

                    /*
                     * Write a image byte array into file system
                     */
                    imageOutFile = new FileOutputStream("D:\\Users\\Vinoth\\workspace\\Testing\\image_converted_Vinoth_2.jpg");
                    imageOutFile.write(imageByteArray);
                }
        imageOutFile.close();

        System.out.println("Image Successfully Manipulated!");
    }

            catch (FileNotFoundException e) {
        System.out.println("Image not found" + e);
    } catch (IOException ioe) {
        System.out.println("Exception while reading the Image " + ioe);
    }

}

/**
 * Encodes the byte array into base64 string
 * @param imageByteArray - byte array
 * @return String a {@link java.lang.String}
 */
public static String encodeImage(byte[] imageByteArray){        
    return Base64.encodeBase64URLSafeString(imageByteArray);        
}

/**
 * Decodes the base64 string into byte array
 * @param imageDataString - a {@link java.lang.String} 
 * @return byte array
 */
public static byte[] decodeImage(String imageDataString) {      
    return Base64.decodeBase64(imageDataString);
}

}
}

1 个答案:

答案 0 :(得分:0)

只是不要使用byte[]转换为Base64字符串,然后搜索&#34; SUkq&#34;。

SUkq表示3个字节(ASCII II* = byte[] { 73, 73, 42 }),但是当相同的3个字节移位1或2个位置时,会发生完全不同的字符串,需要5个字母。

仅包含字节的代码:

    byte[] imageData = Files.readAllBytes(file.toPath());

    final byte[] soughtBytes = { 73, 73, 42 };
    int from = indexOf(imageData, soughtBytes, 0);
    from += soughtBytes.length;
    int to = indexOf(imageData, soughtBytes, from);
    if (to == -1) {
        throw new IllegalArgumentException();
    }
    byte[] imageByteArray = Arrays.copyOfRange(imageData, from, to);

    Path imageOutFile = Paths.get(
                "D:\\Users\\Vinoth\\workspace\\Testing\\image_converted_Vinoth_2.jpg");
    Files.write(imageOutFile, imageByteArray);
}

static int indexOf(byte[] totalBytes, byte[] soughtBytes, int start) {
    for (int index = start; index <= totalBytes.length - soughtBytes.length; ++index) {
        boolean equal = true;
        for (int i = 0; i < soughtBytes.length; ++i) {
            if (totalBytes[index + i] != soughtBytes[i]) {
                equal = false;
                break;
            }
        }
        if (equal) {
            return index;
        }
    }
    return -1;
}

这将字节保存在前两个&#34; II *&#34;

之间。

未经过测试。