Estou na seguinte situação: Preciso ler um arquivo .pdf e verificar se nele existe alguma imagem, caso existir eu preciso apresentar essa imagem para o usuário junto com a legenda(que seria um texto normal, logo após a imagem).
/**
* @author Fernando H. Gomes
*
* Extrai imagens de um pdf criando varios Files no outputpath. Cada File é uma imagen extraida.<br/>
* A nomenclatura padrão de saida é "Image_P[NumeroPagina]_[Cont_Imagen_P_Pagina]"
*
* @param sourcePdf
* @param outputPath
*/
public static void ExtractImagesFromPDF(String sourcePdf, String outputPath)
{
try
{
PdfReader pdf = new PdfReader(sourcePdf);
//percorrendo as paginas do pdf
for (int pageNumber = 1; pageNumber <= pdf.getNumberOfPages(); pageNumber++)
{
PdfDictionary pg = pdf.getPageN(pageNumber);
PdfDictionary res = (PdfDictionary)PdfReader.getPdfObject(pg.get(PdfName.RESOURCES));
PdfDictionary xobj = (PdfDictionary)PdfReader.getPdfObject(res.get(PdfName.XOBJECT));
//pegando o XOBJECT da pagina. que é o que contem as keys q serão usada pra identificar cada "atributo" na pagina
if (xobj != null)
{
int cont_img_por_pagina = 0;
//percorrendo os "atributos" da pagina
for(Iterator it = xobj.getKeys().iterator(); it.hasNext();)
{
PdfObject obj = xobj.get((PdfName) it.next());
/* An indirect object is an object that has been labeled so that it can be referenced by other objects. Any type of PdfObject
* may be labeled as an indirect object. An indirect object consists of an object identifier, a direct object, and the endobj
* keyword. The object identifier consists of an integer object number, an integer generation number, and the obj keyword.
* This object is described in the 'Portable Document Format Reference Manual version 1.7' section 3.2.9 (page 63-65).
*/
if (obj.isIndirect())
{
//pego o dicionario de chave-valor do meu "atributo"
PdfDictionary tg = (PdfDictionary)PdfReader.getPdfObject(obj);
PdfName type = (PdfName)PdfReader.getPdfObject(tg.get(PdfName.SUBTYPE));
//verifico se a propriedade subtype é do tipo IMAGE
if (PdfName.IMAGE.equals(type))
{
//pego os bytes do meu objeto
int XrefIndex =((PRIndirectReference)obj).getNumber();
PdfObject pdfObj = pdf.getPdfObject(XrefIndex);
PdfStream pdfStrem = (PdfStream)pdfObj;
byte[] bytes = PdfReader.getStreamBytesRaw((PRStream)pdfStrem);
if ((bytes != null))
{
//escrevo como um arquivo que depois eu vou usar em algum lugar
cont_img_por_pagina++;
FileOutputStream fw = new FileOutputStream(outputPath+"Image_P"+pageNumber+"_" + cont_img_por_pagina);
fw.write(bytes);
fw.flush();
fw.close();
}
}
}
}
}
}
pdf.close();
}
catch(Exception e)
{
e.printStackTrace();
}
Os créditos do código nao são só meus… esse foi um método que eu montei pra min…
tive como base varios links. principalmente na mailList do próprio iText
Fabinhoocara, só funciona para JPEG/JPG!
O Formato PDF suporta apenas imagens JPEG/JPG e bits primarios, se sua imagens não for um JPEG/JPG ela vai ser transformada em bits primarios e para transforma-la novamente
em imagem voce vai ter que sofrer ^^
vai ter que utilizar as informações de color-space, bits significativos, bit por componente, etc… que vem junto com a tag da imagen no pdf e remonta-la …
é um trabalhinho chato,
eu tentei fazer uma gambiarra utilzando umas classes do PDF RENDERER da sun , que ja tinha umas lógicas q tratavam isso…
GL…
Achei esse código entre uma dificuldade que tive aqui.
Achei excelente e fui testar!
Realmente usando apenas iText não é possivel retornar uma imagem sem saber a sua extensão.
Entretanto
é possível deixar que o java trate isso usando o
if ((bytes != null))
{
//escrevo como um arquivo que depois eu vou usar em algum lugar
cont_img_por_pagina++;
FileOutputStream fw = new FileOutputStream(saida+"Image_P"+pageNumber+"_" + cont_img_por_pagina+".jpg");
//código adicional ao proposto
BufferedImage buff = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIO.write(buff, "jpg", fw);
fw.write(bytes);
fw.flush();
fw.close();
}
então o java pega os bytes obtidos no código anterior e converte para os formatos padrões dele de imagem.
o problema é que a qualidade da imagem já foi comprimida pelo pdf então mesmo que você mude a extensão a qualidade não muda muito.
mas mesmo assim obrigado pela solução.
E vim aqui contribuir com uma outra parte de código.