Unable to encode a tiff file properly, Some characters are not encoding

蹲街弑〆低调 提交于 2019-12-13 07:52:13

问题


I have TIFF file which contains multiple images , I will need to loop through that TIFF file to extract the images seperately , I have used base64 encode, then used substring to seperate the images and used base64 decode to write in a filesystem, However only some images are able to extract.

Example : I have 7 Images in a tiff file but it extracted only 4 images.

So I have write the encoded data to a file and read that and I can only able to see the II* encode character as 4 places instead of 7 .. When I open the TIFF file using notedpad , I can see 7 II* . Please advise , the best method to do this.

I have tried to decode the ecoded file and it is correct, It has 7 II* , however in the ecoded file I can only see the 4 encoded(SUkq) value of II*.

I can't use the below code , as my TIFF file contains header part before the II* which will need to remove before I use the below method.

class

 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();
    }
}

so Im using the below code , this is just to extract the first image .

Class

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:


Simply do not use a conversion of byte[] to a Base64 String and then search "SUkq".

SUkq represent 3 bytes (ASCII II* = byte[] { 73, 73, 42 }), but when those same 3 bytes are shifted 1 or 2 positions, a totally different string happens, needing 5 letters.

The code with byte only:

    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;
}

This saves the bytes between the first two "II*".

Not tested.



来源:https://stackoverflow.com/questions/38418111/unable-to-encode-a-tiff-file-properly-some-characters-are-not-encoding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!