Good afternoon. I have a JAR file to which I have attached some images as resources in a folder called logos. I am being told to do this due to security restrictions (we don't want the image files to be exposed in the same folder as the JAR). I first tried to load these images in as if they were a File object, but that obviously doesn't work. I am now trying to use an InputStream to load the image into the required PDImageXObject, but the images are not rendering into the PDF. Here is a snippet of the code which I am using:
String logoName = "aLogoName.png";
PDDocument document = new PDDocument();
// the variable "generator" is an object used for operations in generating the PDF
InputStream logoFileAsStream = generator.getClass().getResourceAsStream("/" + logoName);
PDStream logoStream = new PDStream(document, logoFileAsStream);
PDImageXObject logoImage = new PDImageXObject(logoStream, new PDResources());
PDPage page = new PDPage(new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth()));
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.drawImage(logoImage, 500, 100);
Note that I have verified that the resource is getting loaded in correctly, as using logoFileAsStream.available() returns a different value for various logos. After running this code, the image does not actually get drawn on the PDF, and upon opening it, the error message "An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem." appears. Could someone please help me figure what's wrong with that code snippet/a different solution to load my images in as a resource from the JAR? Thanks so much. Let me know if more details are needed/clarification.
This PDImageXObject constructor is for internal PDFBox use only. You can use
PDImageXObject.createFromByteArray(document, IOUtils.toByteArray(logoFileAsStream), logoName /* optional, can be null */)
for maximum flexibility, or if you know it is always a PNG file
LosslessFactory.createFromImage(document, ImageIO.read(logoFileAsStream))
don't forget to close logoFileAsStream and contentStream.
Related
How can I transform a PDF with forms made in Adobe Livecycle to a simple image PDF using Java?
I tried using Apache PDFBox but it can't save as image a PDF with forms.
This is what I tried(from this question: Convert PDF files to images with PDFBox)
String pdfFilename = "PDForm_1601661791_587488.pdf";
try (PDDocument document = PDDocument.load(new File(pdfFilename))) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
ImageIOUtil.writeImage(bim, pdfFilename + "-" + (page+1) + ".png", 300);
}
} catch (IOException ex) {
Logger.getLogger(StartClass.class.getName()).log(Level.SEVERE, null, ex);
}
But is not working, the result is an image where it writes that "The document you are trying to load requires Adobe Reader 8 or higher.
I guess is not possible, I tried many libraries and none worked.
This is how I solved the problem:
I used an external tool - PDFCreator.
In PDFCreator I created a special printer that prints and saves the PDF without asking any questions(you have these options in PDFCreator).
This is simple to reproduce in PDFCreator because in the Debug section you have an option to load a config file, so I have this file prepared, I just install PDFCreator and load the config file.
If you will use my INI file in the link above you should know that the resulted PDF is automatically saved in the folder: "current user folder/Desktop/temporary".
The rest of the job is done from Java using Adobe Reader, the code is in my case:
ProcessBuilder pb = new ProcessBuilder(adobePath, "/t", path+"/"+filename, printerName);
Process p = pb.start();
This code opens my PDF in AdobeReader, prints the PDF to the specified virtual printer, and exists automatically.
"adobePath" is the path to the adobe executable
path+"/"+filename is the path to my PDF.
"printerName" is the name of the virtual printer created in PDFCreator
So this is not a pure Java solution and in the future, I intend to use Apache PDFBox to generate my PDF's in a format that is compatible with browsers and all readers...but this works also.
I have managed to create my own pdf documents with the help of PdfDocument Class.
But what if I already have a pdf in my (let's say) assets folder and I want to e.g. draw something on it. Is it possible?
I have my
PdfDocument document;
But how can i read the powerpoint i have inside my project?
I am guessing i have to use a File but i cannot work this out.
I tried something like this, although I know it is wrong
PdfDocument document = new PdfDocument(getAssets().open("powerpoint"));
From what I understand you ask two questions:
But what if I already have a pdf in my (let's say) assets folder and I
want to e.g. draw something on it. Is it possible?
With the android PdfDocument class, you can create a PDF out of Web content (via WebView), a Canvas (using views or the native Canvas drawing API), or an image. You have to use third-party PDF libraries (like iText or the PDFBox Android port) to change existing PDFs.
But how can i read the powerpoint i have inside my project?
For displaying powerpoint there is a separate project called 'pptviewer-android'. However it is not maintained anymore, so if you have problems you probably have to figure those out by yourself. An examplary use can be found here.
PPTViewer pptViewer = (PPTViewer) findViewById(R.id.pptviewer);
pptViewer.setNext_img(R.drawable.next)
.setPrev_img(R.drawable.prev)
.setSettings_img(R.drawable.settings)
.setZoomin_img(R.drawable.zoomin)
.setZoomout_img(R.drawable.zoomout);
pptViewer.loadPPT(this,"/home/powerpoint.pptx");
Not sure whether I have correctly understood your problem statement:
Please try this out:
if (Desktop.isDesktopSupported()) {
try {
File fileToOpen = new File("/assets/file.pdf");
Desktop.getDesktop().open(fileToOpen);
} catch (IOException ex) {
// log Error
}
}
I am using org.apache.poi.xwpf.converter.xhtml.XHTMLConverter class to convert docx to html. Below is my groovy code
public Map convert(String wordDocPath, String htmlPath,
Map conversionParams)
{
log.info("Converting word file "+wordDocPath)
try
{
...
String notificationWorkingFolder = "C:\tomcats\Notification\store\Notification1234"
FileInputStream fis = new FileInputStream(wordDocPath);
XWPFDocument document = new XWPFDocument(fis);
XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(new File(notificationWorkingFolder)));
File htmlFile = new File(htmlPath);
OutputStream out = new FileOutputStream(htmlFile)
XHTMLConverter.getInstance().convert(document, out, options);
log.info("Converted to HTML file "+htmlPath)
return [success:true,htmlFileName:getFileName(htmlPath)]
}
catch(Exception e)
{
log.error("Exception :"+e.getMessage(),e)
return [success:false]
}
}
The above code is converting docx to html successfully, but if docx contains any images it puts <img src="C:\tomcats\Notification\store\Notification1234\word\media\image1.png"> but do not copy the image to that folder. As a result, when I open html tag, all images appears empty. Am I missing something in code? Is there a way to generate an image srouce link instead of absolute path, like <img src="http://localhost:8080/webapp/image1.png">
I got answer for first question from this link lychaox.com/java/poi/Word07toHtml.html. I had to add one line of code options.setExtractor(new FileImageExtractor(imageFolderFile)); to generate images.
Second question I resolved by pattern search and replacement.
Even with proper usage, it's worth noting that XHTMLConverter uses XHTMLMapper, which does not process headers, footers, or VML Images. Any images falling into those categories will be lost.
The PDFConverter is more fully featured, but also uses the GPL licensed library, iText.
I am trying to crop image.There is an ajax call made to the server end where cropping takes place and original file gets replaced with cropped image.
Now when i get back the control, i still see the old image even though cropped image exists at the same location.
Changes reflect only after page refresh which i don't want users to do it.Code for crop image is as follows
BufferedImage originalImgage = ImageIO.read(new File(filePath+"\\"+subFolder+"\\"+fileName));
ImageIO.write(originalImgage,extention,new File(filePath+"\\"+subFolder+"\\"+dateStamp+"_"+fileName));//save original image
BufferedImage SubImgage = originalImgage.getSubimage(xAxis,yAxis,width,height);
File outputfile = new File(filePath+"\\"+subFolder+"\\"+fileName);
ImageIO.write(SubImgage,extention,outputfile);
pls help
Thanks
Try to replace the image src parameter with the new path returned from ajax in ajax success call back.
Well after struggling a lot finally found the problem.The image is cached by the browser. So whenever u do any operations on image on the same file location , the latest copy is not download.Instead old image from cache is still referred.
Hence the solution was to make browser download latest copy.This was simple.
Append dummy parameter to file path forcing browser to download
rand = new Date().getTime();
var image_Path = filePath+"?crop="+rand
I am currently working on a project that allows the user to input a url, such as http://www.google.com and the user is able to edit the html code of the page. So far I save the edited file as an html document when the JTextArea has a key released. Here is the source code that I use:
String s = jTextArea1.getText();
PrintStream ps = new PrintStream(new FileOutputStream(new File("HTML.htm")));
ps.print(s);
ps.close();
this.resetPage();
The last line of code calls this bit of source code (this is actually where I attempt to update the page with the user's input:
File f = new File("HTML.htm");
URL u =f.toURI().toURL();
jEditorPane1.setPage(u);
All the proper exceptions are caught. It updates the text on the page once. All the images are blank (which I expected because the paths were all local) but that should have no real effect on the other html in the document.
When I open the HTML.htm file in notepad++ the file IS being updated but the jEditorPane is not getting updated with the new html script.
Also, the JEditorPane has its Editable vale set to false.
When I open the file in Chrome, it gets the fully updated script.
From the JEditorPane setPage(URL) API description:
To force a document reload it is necessary to clear the stream description property of the document. The following code shows how this can be done:
Document doc = jEditorPane.getDocument();
doc.putProperty(Document.StreamDescriptionProperty, null);
try this
File f = new File("HTML.htm");
URL u =f.toURI().toURL();
jEditorPane1.setPage(u);
jEditorPane1.updateUI();