无法连接code TIFF文件正确,某些字符不编码 [英] Unable to encode a tiff file properly, Some characters are not encoding

查看:485
本文介绍了无法连接code TIFF文件正确,某些字符不编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个图像的TIFF文件,我需要循环通过TIFF文件单独提取图像,
我用的base64 EN code,然后用子串单独的图像和使用的base64德code在文件系统写的,
 但是,只有一些图片都可以提取。

例子:我有一个TIFF文件7张图片,但它仅提取4图像。

所以我有恩codeD数据写入到文件和读取,我可以只能够看到II * EN code字符作为4位,而不是7 ..
当我使用notedpad打开TIFF文件,我可以看到7 * II。请指教,要做到这一点的最好方法。

我试图去code中的E codeD文件,它是正确的,它具有7 II *,但在E codeD文件我只能看到4间codeD二(SUkq)值*。

我不能使用低于code,因为我的TIFF文件中包含的II *这将需要删除之前,我用下面的方法之前头部分。

 公共无效doitJAI()抛出IOException
    FileSeekableStream SS =新FileSeekableStream(D:\\\\ \\\\用户\\\\ Vinoth工作区\\\\ image.tif);
    ImageDe codeR DEC =图片codec.createImageDe codeR(TIFF,SS,NULL);
    诠释计数= dec.getNumPages();
    蒂芬codeParam参数=新蒂芬codeParam();
   param.setCom pression(蒂芬codeParam.COM preSSION_GROUP4);
    param.setLittleEndian(假); //英特尔
    的System.out.println(这TIF有+数+图像(S));
    的for(int i = 0; I<计数;我++){
        的RenderedImage页= dec.de codeAsRenderedImage(I)
        文件f =新的文件(D:\\\\ \\\\用户\\\\ Vinoth工作区\\\\ single_+ I +。TIF);
        的System.out.println(拯救+ f.getCanonicalPath());
        ParameterBlock中PB =新ParameterBlock();
        pb.addSource(页);
        pb.add(f.toString());
        pb.add(TIFF);
        pb.add(参数);
        RenderedOp R = JAI.create(文件存储PB);
        r.dispose();
    }
}

因此​​使用下面的code IM,这仅仅是提取第一张图像。

 公共类SplitTIFFFile {公共静态无效的主要(字串[] args)抛出IOException
    新SplitTIFFFile()doitJAI();
}档案文件=新的文件(D:\\\\ \\\\用户\\\\ Vinoth工作区\\\\ \\\\测试image.tif);    尝试{                FileOutputStream中imageOutFile;
                / * * imageOutFile / TRY(/ *
                 *从读取文件系统中的图像文件
                 * /的FileInputStream imageInFile =新的FileInputStream(文件)){
                    字节为imageData [] =新的字节[(INT)file.length()];
                    imageInFile.read(为imageData);
                    / *
                    *转换图像字节数组转换为Base64编码字符串
                    * /
                    字符串imageDataString = EN $ C $的CImage(为imageData);
                    字符串结果= imageDataString.substring(imageDataString.indexOf(SUkq),imageDataString.indexOf(SUkq));
                    / *
                    *转换为Base64字符串到图片的字节数组
                    * /
                    字节[] = imageByteArray德$ C $的CImage(结果);                    / *
                     *写图像字节数组转换成文件系统
                     * /
                    imageOutFile =新的FileOutputStream(D:\\\\ \\\\用户\\\\ Vinoth工作区\\\\ \\\\测试image_converted_Vinoth_2.jpg);
                    imageOutFile.write(imageByteArray);
                }
        imageOutFile.close();        的System.out.println(图像操纵成功!);
    }            赶上(FileNotFoundException异常五){
        的System.out.println(没有找到图片+ E);
    }赶上(IOException异常IOE){
        的System.out.println(+ IOE当读取图像异常);
    }}/ **
 *恩codeS中的字节数组的base64字符串
 * @参数imageByteArray - 字节数组
 * @返回一个字符串{@link java.lang.String中}
 * /
公共静态字符串连接$ C $的CImage(字节[] imageByteArray){
    返回Base64.en codeBase64URLSafeString(imageByteArray);
}/ **
 *德codeS中的Base64字符串转换成字节数组
 * @参数imageDataString - 一个{@link java.lang.String中}
 * @返回字节数组
 * /
公共静态的byte []德$ C $的CImage(字符串imageDataString){
    返回Base64.de codeBase64(imageDataString);
}}
}


解决方案

只要不使用的转换的byte [] 到Base64字符串,然后搜索SUkq

SUkq重新present 3个字节(ASCII II * =字节[] {73,73,42} ),但是,当这些相同的3个字节偏移1或2位,一个完全不同的字符串发生,需要5个字母。

在code只用一个字节:

 字节[]为imageData = Files.readAllBytes(file.toPath());    最后一个字节[] = soughtBytes {73,73,42};
    从=的indexOf INT(的imageData,soughtBytes,0);
    从+ = soughtBytes.length;
    int值=的indexOf(为imageData,soughtBytes从);
    如果(至== -1){
        抛出新抛出:IllegalArgumentException();
    }
    字节[] = imageByteArray Arrays.copyOfRange(为imageData,从,到);    路径imageOutFile = Paths.get(
                D:\\\\ \\\\用户\\\\ Vinoth工作区\\\\ \\\\测试image_converted_Vinoth_2.jpg);
    Files.write(imageOutFile,imageByteArray);
}静态INT的indexOf(字节[] totalBytes,字节[] soughtBytes,INT启动){
    对于(INT指数=启动;指数< = totalBytes.length - soughtBytes.length ++指数){
        布尔等于= TRUE;
        的for(int i = 0; I< soughtBytes.length ++我){
            如果(totalBytes [索引+ 1]!= soughtBytes [I]){
                等于= FALSE;
                打破;
            }
        }
        如果(等于){
            返回指数;
        }
    }
    返回-1;
}

这节省了字节的前两个II *。

未经测试。

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

}
}

解决方案

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.

这篇关于无法连接code TIFF文件正确,某些字符不编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆