我有包含多个图像的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);
}
}
}
答案 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;
之间。未经过测试。