2016-07-17 12 views
-1

У меня есть файл TIFF, который содержит несколько изображений, мне нужно будет пропустить этот файл TIFF, чтобы извлекать изображения отдельно, Я использовал кодировку base64, а затем использовал подстроку для разделения изображений и использования декодирования base64 для записи в файловой системе, Однако только некоторые изображения могут извлекаться.Невозможно правильно закодировать tiff-файл, некоторые символы не кодируются

Пример: У меня есть 7 изображений в файле tiff, но он извлекал только 4 изображения.

Так что я записал закодированные данные в файл и прочитал это, и я могу видеть только символ кодировки II * как 4 места вместо 7 .. Когда я открываю файл TIFF с помощью замеченной панели, я могу видеть 7 II *. Пожалуйста, посоветуйте, лучший способ сделать это.

Я попытался декодировать закодированный файл, и это правильно, оно имеет 7 II *, однако в закодированном файле я могу видеть только 4 закодированное (SUkq) значение II *.

Я не могу использовать приведенный ниже код, так как мой файл 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(); 
    } 
} 

так Im используя приведенный ниже код, это просто извлечь первое изображение.

Класс

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 * двумя пробелами спереди и двумя пробелами после II *? – Vinoth

+0

Вы знаете, что файлы tiff внутренне используют смещения для многих ссылок на структуру и что замена некоторых последовательностей другими может нарушить эти ссылки? Кроме того, вы, конечно, хотите заменить только значения определенных тегов (или областей памяти, на которые они ссылаются), а не, например. в данных изображения. – mkl

ответ

0

Просто не использовать преобразование byte[] в Base64 строку, а затем искать "SUkq".

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

Это экономит байты между первые два "II *".

Не проверено.