2017-06-22 30 views
5

Próbuję wstawić obraz JPG do pliku PDF. Niektóre obrazy jpg działają poprawnie, ale w niektórych przypadkach otrzymuję następujący wyjątek.Przedwczesne EOF podczas odczytywania wyjątku JPG podczas zapisywania obrazów JPG do formatu pdf przy użyciu itext

java.io.IOException: Premature EOF while reading JPG. 
    at com.itextpdf.text.Jpeg.processParameters(Jpeg.java:218) 
    at com.itextpdf.text.Jpeg.<init>(Jpeg.java:117) 
    at com.itextpdf.text.Image.getInstance(Image.java:279) 
    at com.itextpdf.text.Image.getInstance(Image.java:241) 
    at com.itextpdf.text.Image.getInstance(Image.java:364) 

Poniżej znajduje się kod, którego używam.

import com.itextpdf.text.Document; 
import com.itextpdf.text.DocumentException; 
import com.itextpdf.text.Image; 
import com.itextpdf.text.pdf.PdfPCell; 
import com.itextpdf.text.pdf.PdfPTable; 
import com.itextpdf.text.pdf.PdfWriter; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 

public class ImagesNextToEachOther { 

    public static final String DEST = "/home/Documents/pdftest/hello.pdf"; 

    public static final String IMG1 = "/home/Documents/pdftest/2.jpg"; 

    public static void main(String[] args) throws IOException, 
      DocumentException { 
     File file = new File(DEST); 
     file.getParentFile().mkdirs(); 
     new ImagesNextToEachOther().createPdf(DEST); 
    } 

    public void createPdf(String dest) throws IOException, DocumentException { 
     Document document = new Document(); 
     PdfWriter.getInstance(document, new FileOutputStream(dest)); 
     document.open(); 
     PdfPTable table = new PdfPTable(1); 
     table.setWidthPercentage(100); 
     table.addCell(createImageCell(IMG1)); 
     document.add(table); 
     document.close(); 
    } 

    public static PdfPCell createImageCell(String path) throws DocumentException, IOException { 
     Image img = Image.getInstance(path); 
     PdfPCell cell = new PdfPCell(img, true); 
     return cell; 
    } 
} 

Otrzymuję błąd w następującej linii w powyższym kodzie.

Image img = Image.getInstance(path); 

path to pełna ścieżka obrazu.

Znalazłem podobne pytanie na SO

Premature EOF while reading JPG using itext

Failure to read JPEG file from byte[]

Ale to nie rozwiązuje mojego problemu.

Oto link do jednego takiego obrazu

https://dl.dropboxusercontent.com/u/46349359/image.jpg

+3

Prześlij jeden ze swoich plików JPG, który powoduje wyjątek. Spodziewam się, że zostanie ona rozbita w bardzo subtelny sposób. –

+0

@AmedeeVanGasse zaktualizował pytania za pomocą przykładowego obrazu. – ashishjmeshram

Odpowiedz

7

Jak Amedee już wyjaśniono w swoich uwag, JPG jest zepsuty. Możesz to sprawdzić samodzielnie, otwierając obraz w numerze GIMP, a następnie wybierając File > Overwrite image.jpg, GIMP naprawi obraz, a błąd EOF zniknie.

Zrobiłem to dla ciebie, a wynik jest:

enter image description here

Jeśli pobranie tego obrazu, i używać go z kodem, błąd nie występuje.

Jak to mi pomaga? możesz zapytać. Widzę obraz w przeglądarce. Widzę obraz w przeglądarce obrazów. Dlaczego nie rozwiążesz tego problemu w iText?

Odpowiedź jest prosta: JPG jest natywnie obsługiwany przez PDF, co oznacza, że ​​możemy umieścić dokładną kopię wszystkich bajtów obrazu JPG w pliku PDF. Jednak zanim to zrobimy, iText wykona kontrolę poprawności obrazu. Kiedy to sprawdzanie poprawności nie powiedzie się, iText będzie (i powinien) odrzucić obraz, ponieważ istnieje duża szansa, że ​​plik PDF zawierający taki "uszkodzony" obraz wyświetli komunikat o błędzie, jeśli go użyjemy.

Przeglądarki obrazów lub narzędzia do edycji obrazu (takie jak GIMP) są bardziej tolerancyjne. Ignorują fakt, że obraz nie jest dobrze uformowany. W przypadku GIMP narzędzie naprawia błędy i daje możliwość "nadpisania" obrazu do przechowywania poprawek.

Obecnie nie ma planów, aby iText wykonał takie poprawki. Udostępniliśmy taką poprawkę dla uszkodzonych plików TIFF, ale nawet wtedy domyślnie odrzucamy uszkodzone obrazy. Jeśli chcesz, aby iText naprawiał uszkodzony plik TIFF, musisz ustawić flagę, ponieważ większość naszych klientów woli uzyskać wyjątek niż ryzyko dodania obrazu, który jest automatycznie naprawiany.Jeśli jesteś klientem iText, możesz wysłać prośbę o wsparcie do funkcji "naprawiania uszkodzonego obrazu" do iText; jeśli jesteś klientem iText, nie musisz go dodawać samodzielnie, i opublikuj go w AGPL wraz z resztą kodu projektu (jak wiesz, AGPL iText zobowiązuje Cię do opublikowania pełny kod źródłowy projektu w większości przypadków).