无法连接code TIFF文件正确,某些字符不编码 [英] Unable to encode a tiff file properly, Some characters are not encoding
问题描述
我有一个包含多个图像的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屋!