2016-07-17 9 views
-1

여러 이미지가 포함 된 TIFF 파일이 있습니다. 이미지를 별도로 추출하려면 해당 TIFF 파일을 반복해야합니다. base64 인코딩을 사용한 다음 하위 문자열을 사용했습니다. 이미지를 분리하고 base64 디코드를 사용하여 파일 시스템에 쓰려면 그러나 일부 이미지 만 추출 할 수 있습니다.TIFF 파일을 제대로 인코딩 할 수 없습니다. 일부 문자는 인코딩되지 않습니다.

예 : Tiff 파일에 7 개의 이미지가 있지만 4 개의 이미지 만 추출했습니다.

인코딩 된 데이터를 파일에 쓰고 읽음으로써 II * 인코딩 문자를 7 대신 4 자리로 볼 수 있습니다 .. 메모장을 사용하여 TIFF 파일을 열면 7 II *. 이를 수행하는 가장 좋은 방법을 조언하십시오.

ecoded 파일을 디코딩하려고 시도했지만 올바른 것입니다. 그러나 ecoded 파일에서는 II *의 4 인코딩 (SUkq) 값만 볼 수 있습니다.

아래의 코드를 사용할 수 없습니다. 아래의 코드를 사용하기 전에 제거해야 할 II * 앞에 TIFF 파일에 헤더가 포함되어 있습니다.

클래스

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

Tiff는 바이너리 형식입니다. 일반적으로 문자열 연산을 사용하여 이진 데이터를 텍스트 형식으로 강제 변환하지 않고 대신 이진 연산을 사용하는 것이 좋습니다. – mkl

+0

안녕하세요, tiff 파일을 열고 일부 문자열을 바꿀 수있는 방법을 조언 할 수 있습니까? II *를 정면 2 칸, II * 2 칸 대체해야합니까? – Vinoth

+0

tiff 파일은 많은 구조 참조에 대해 내부적으로 오프셋을 사용하며 특정 시퀀스를 다른 시퀀스로 대체하면 이러한 참조가 손상 될 수 있다는 것을 알고 계십니까? 또한 특정 태그 (또는 참조하는 메모리 영역)의 값을 바꾸기를 원할뿐입니다. 이미지 데이터에서. – mkl

답변

0

은 간단하게 "SUkq"를 검색 한 후 Base64로 문자열에 byte[]의 변환을 사용하지 않습니다.

SUkq는 3 바이트 (ASCII II* = byte[] { 73, 73, 42 })를 나타내지 만 동일한 3 바이트가 1 또는 2 위치로 이동하면 완전히 다른 문자열이 발생하여 5자를 필요로합니다. 단지 바이트와

코드 : 이것은 처음 두 "II *" 사이의 바이트 저장

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

.

테스트되지 않았습니다.