I'm to use the Java printing API to print a JPG to an Epson PictureMate photo printer. I want the print to take up the entire page. The image prints but it has an eighth of an inch of unprinted space on right edge. Here's the code I'm using:
public void printImage(File image) throws Exception {
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(OrientationRequested.REVERSE_LANDSCAPE);
aset.add(MediaSizeName.JAPANESE_POSTCARD);
DocPrintJob printerJob = printService.createPrintJob();
FileInputStream fis = new FileInputStream(image);
Doc doc = new SimpleDoc(fis, DocFlavor.INPUT_STREAM.JPEG, null);
printerJob.print(doc, aset);
fis.close();
}
I thought the the JAPANESE_POSTCARD size was correct but it seems to small for 4"x6" prints. I also tried setting MediaPrintableArea to 4"x6" but that didn't work either. Any ideas?
I know there is some (potential) internal wrangling of the Paper that goes on after you pass it to the PrintJob, basically it's trying to valid that the paper size and margins can work with the specified printer (from experience).
However, you might to take a read of http://www.jpedal.org/PDFblog/2009/06/java-printing-page-size-problem/ as it might have some ideas on how to over come some of them.
As to how to them apply that back to the PrintServices API is another question ;)
Related
I am creating a report printer in Java using the LibreOffice SDK and Apache Batik. Using Batik, I draw svgs which I then insert into a LibreOffice Writer document. To properly insert the image, all I found is using a path to load the image from disk and insert it into the document. So far so good, but I have to explicitly save the document to disk in order to read it into libreoffice again.
I tried to use a data url as the image path but it did not work. Are there any possibilities to read an image from a stream or anything else I can use without storing the file to disk?
I found a solution. I realized how to do it when I realized that all my images I added were just image links. So I had to embed the images instead.
To use this, you need:
Access to the XComponentContext
A TextGraphicObject in your document (see the links above)
The image as byte[] or use another stream
The code:
Object graphicProviderObject = xComponentContext.getServiceManager().createInstanceWithContext(
"com.sun.star.graphic.GraphicProvider",
xComponentContext);
XGraphicProvider xGraphicProvider = UnoRuntime.queryInterface(
XGraphicProvider.class, graphicProviderObject);
PropertyValue[] v = new PropertyValue[1];
v[0] = new PropertyValue();
v[0].Name = "InputStream";
v[0].Value = new ByteArrayToXInputStreamAdapter(imageAsByteArray);
XGraphic graphic = xGraphicProvider.queryGraphic(v);
if (graphic == null) {
LOGGER.error("Error loading the image");
return;
}
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, textGraphicObject);
// Set the image
xProps.setPropertyValue("Graphic", graphic);
This worked effortlessly even for my svg images.
Source: https://blog.oio.de/2010/05/14/embed-an-image-into-an-openoffice-org-writer-document/
Is there a way to add additional font styles into Apache Pdfbox?
We're currently trying to work around printing PDFs in our system (currently being done with PDF-Renderer.) I have been looking at various alternatives (pdfbox, jpedal, jPDFPrint)
Our hope is for a free GPL compatible library to use, and as such we're leaning towards pdfbox. I have been able to write some sample code to print out the pdf which 'works'. See below:
PDDocument doc;
try {
doc = PDDocument.load("test.pdf");
doc.print();
} catch (Exception e) {
// Come up with better thing to do on fail.
e.printStackTrace();
}
As I mentioned, this works but the problem I'm running into is that PdfBox doesn't seem to be recognizing the fonts used in the pdf, and as such changes the font being used. As a result the document looks very odd (spacing and character size are different and look bizarre). I routinely see the following log message, or things like it:
Apr 16, 2014 2:56:21 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString
WARNING: Changing font on < > from < NimbusMono > to the default font
Does anyone know of a way (or a reference) on how to approach adding a new fonttype into pdfbox? Or barring that, how to change the default font type?
From what I can tell, pdfbox supports 14 standard fonts. Unfortunately NimbusMono is not one of them. Any guidance would be appreciated.
The unreleased 2.0 version supports the rendering of embedded fonts. You can get it as a snapshot
https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/
or through "svn checkout http://svn.apache.org/repos/asf/pdfbox/trunk/". The API is slightly different from the 1.8.x versions and might change, the best is to look at the code examples. A quick test to see whether your file will be rendered properly is to download the "pdfbox-app"
https://repository.apache.org/content/groups/snapshots/org/apache/pdfbox/pdfbox-app/2.0.0-SNAPSHOT/
and then run the viewer:
java -jar pdfbox-app-2.0.0-20140416.173452-273.jar PDFReader your-file-name.pdf
There's also a print feature.
Good luck!
Update 2016: 2.0 release is out, download it here.
If you have used the 1.8 version, read the migration guide.
I came across this post while trying to solve the same problem. The PDFBox 2.0 API documentation isn't great at the moment.
What you're looking for is the FontFileFinder in Fontbox.
Make sure you're using the full pdfbox-app jar which includes Fontbox.
I've only tried this on Windows but looking at the classes it seems like it supports the other main operating systems.
Here's a simple example class I wrote that writes out a small bit of text in the bottom left corner of a PDF, using a non-standard font.
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import org.apache.fontbox.util.autodetect.FontFileFinder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
public class TestPDFWrite {
public static void main(String[] args) throws IOException {
FontFileFinder fontFinder = new FontFileFinder();
List<URI> fontURIs = fontFinder.find();
File fontFile = null;
for (URI uri : fontURIs) {
File font = new File(uri);
if (font.getName().equals("CHILLER.TTF")) {
fontFile = font;
}
}
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
if (fontFile != null) {
contentStream.setFont(PDType0Font.load(document, fontFile), 12);
} else {
contentStream.setFont(PDType1Font.HELVETICA, 12);
}
contentStream.newLineAtOffset(10, 10);
contentStream.showText("Hello World");
contentStream.endText();
contentStream.close();
document.save("C:/Hello World.pdf");
document.close();
}
}
I ran into a similar problem with PDFBox. PDFs can be printed in a straightforward way using Java's javax.print package. The following code is slightly modified from the API docs for javax.print.
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_C6); //letter size
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(flavor, aset);
if (pservices.length > 0) {
DocPrintJob pj = pservices[0].createPrintJob();
try {
FileInputStream fis = new FileInputStream("test.pdf");
Doc doc = new SimpleDoc(fis, flavor, null);
pj.print(doc, aset);
} catch (FileNotFoundException | PrintException e) {
//do something
}
This code assumes that the printer can accept a PDF directly but it allows you to bypass PDFBox 1.8 branch's wonky font issues.
Do you have any ideas how to print PDF file using standard Java libraries with showing dialog window?
PrinterJob pjob = PrinterJob.getPrinterJob();
if (pjob.printDialog()) {
try {pjob.print();}
catch (PrinterException exc) {
System.out.println(exc);
}
}
I had problems with finding a solution. Was trying to use PDFRenderer, but, i dont know how, it prints my .pdf just on the 1/4 surface of a page... I would be grateful if you could help.
To use the pdfRenderer library I basically follow the step from this guy:
http://lynema.org/2010/12/29/printing-a-pdf-in-java-with-pdfrenderer
As far as why when you print your image is off-scaled it's because of how PDFPrintPage was implemented. The link I showed you above show how to go around the problem. As for the source code for PDFPrintPage the link below has it:
http://juixe.com/techknow/index.php/2008/01/17/print-a-pdf-document-in-java/
I try to understand the logic in PDFPrintPage and I manipulate my image size and the paper size to fit and now I'm printing PDF successfully using PDFRenderer
If the PDF is not A4, you will need to configure some transformations to scale it.
JPS has lots of options to control printing.
We are using Java2D to resize photos uploaded to our website, but we run into an issue (a seemingly old one, cf.: http://forums.sun.com/thread.jspa?threadID=5425569) - a few particular JPEGs raise a CMMException when we try to ImageIO.read() an InputStream containing their binary data:
java.awt.color.CMMException: Invalid image format
at sun.awt.color.CMM.checkStatus(CMM.java:131)
at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89)
at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1326)
...
(snipped the remainder of the stack trace, which is our ImageIO.read() call, servlet code and such)
We narrowed it down to photos taken on specific cameras, and I selected a photo that triggers this error: http://img214.imageshack.us/img214/5121/estacaosp.jpg.
We noticed that this only happens with Sun's JVM (on Linux and Mac, just tested it on 1.6.0_20) - a test machine with OpenJDK reads the same photos without a hitch, possibly due to a different implementation of the JPEG reader.
Unfortunately, we are unable to switch JVMs in production, nor to use native-dependent solutions such as ImageMagick ( http://www.imagemagick.org/ ).
Considering that, my question is: Does a replacement for ImageIOs JPEG reader which can handle photos such as the linked one exist? If not, is there another 100% pure Java photo resizing solution which we can use?
Thank you!
One possibly useful library for you could be the Java Advanced Imaging Library (JAI)
Using this library can be quite a bit more complicated than using ImageIO but in a quick test I just ran, it did open and display the problem image file you linked.
public static void main(String[] args) {
RenderedImage image = JAI.create("fileload", "estacaosp.jpg");
float scale=(float) 0.5;
ParameterBlock pb = new ParameterBlock();
pb.addSource(image);
pb.add(scale);
pb.add(scale);
pb.add(1.0F);
pb.add(1.0F);
pb.add(new InterpolationNearest() );// ;InterpolationBilinear());
image = JAI.create("scale", pb);
// Create an instance of DisplayJAI.
DisplayJAI srcdj = new DisplayJAI(image);
JScrollPane srcScrollPaneImage = new JScrollPane(srcdj);
// Use a label to display the image
JFrame frame = new JFrame();
frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
After running this code the image seems to load fine. It is then resized by 50% using the ParamaterBlock
And finally if you wish to save the file you can just call :
String filename2 = new String ("tofile.jpg");
String format = new String ("JPEG");
RenderedOp op = JAI.create ("filestore", image, filename2, format);
I hope this helps you out. Best of luck.
Old post, but for future reference:
Inspired by this question and links found here, I've written a JPEGImageReader plugin for ImageIO that supports JPEG images with these kind of "bad" ICC color profiles (the "issue" is the rendering intent in the ICC profile is incompatible with Java's ColorConvertOp). It's plain Java and does not require JAI.
The source code and linked binary builds are freely available from the TwelveMonkeys project on GitHub.
I faced the same issue. I was reluctant to use JAI as it is outdated but it looks like it's the shortest solution.
This code converts an InputStream to a BufferedImage, using sun's ImageIO (fast) or in the few cases where this problem occur, using JAI:
public static BufferedImage read(InputStream is) throws IOException {
try {
// We try it with ImageIO
return ImageIO.read(ImageIO.createImageInputStream(is));
} catch (CMMException ex) {
// If we failed...
// We reset the inputStream (start from the beginning)
is.reset();
// And use JAI
return JAI.create("stream", SeekableStream.wrapInputStream(is, true)).getAsBufferedImage();
}
}
We are looking into silent printing of PDF documents from within Java. The printing will be invoked from the desktop and not through a browser so we cannot use JavaScript. PDF Renderer is an operational solution but their rendering quality is not acceptable. iText does not seem to be pluggable with the Java print service. There are some commercial Java libraries, jPDFPrint by Qoppa, JPedal, and ICEpdf which we have not tried out yet.
Does anybody have any experience with PDF silent printing from Java?
Apache PDFBox. It is currently in incubation, but the PDF printing functionality has been around before that. Internally, it uses the Java Print Services to create a print job, and it also supports silent printing.
Do note that it requires Fontbox as well, and the current (upcoming 0.8.0 release) has included graceful fallback for documents with Type 0 fonts. Type 1 fonts are printed correctly; however in 0.7.3, attempts to print documents with Type 0 fonts will result in an exception being thrown.
Maybe I'm misunderstanding, but why not just use the Print Service API directly? The following works for me (assumes you have the PDF document as a byte array):
DocFlavor flavor = DocFlavor.BYTE_ARRAY.PDF;
PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, null);
if (services.length > 0)
{
DocPrintJob printJob = services[0].createPrintJob();
Doc document = new SimpleDoc(pdfBytes, flavor, null)
printJob.print(document, null);
}
else
{
System.out.println("No PDF printer available.");
}
This works for me:
public void print() {
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, null);
FileInputStream psStream = null;
try {
psStream = new FileInputStream("c:\\test.pdf");
} catch (FileNotFoundException ffne) {
ffne.printStackTrace();
}
if (psStream == null) {
return;
}
if (services.length > 0)
{
PrintService myService = null;
for(PrintService service : services) {
System.out.println(service.getName());
if(service.getName().contains("my printer")) {
myService = service;
break;
}
}
DocPrintJob printJob = myService.createPrintJob();
Doc document = new SimpleDoc(psStream, flavor, null);
try {
printJob.print(document, null);
} catch (PrintException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
System.out.println("No PDF printer available.");
}
}
Have a look at www.pdflib.com. Its comercial but PDFlib Lite is available for free for open source projects. It has bindings for java.
There is an example using JPedal at http://www.jpedal.org/support_egSP.php
You will need the commercial version of IcePdf if you want full font support.
I have experience with making Acrobat (Reader or Full) do the printing, but it's anything but silent (it is unattended, though - just depends on how 'silent' the silent requirement is). If there's interest, I can shoot you the native code that makes the required DDE calls.
iText is intended for creating PDF files (per a post I saw from the author), and thus probably isn't what you want.
I've used Qoppa's jPDFPrint quite successfully for exactly this purpose, but it's not cheap. If you can afford it, it's the most robust solution I've found thus far. I've also been very impressed with the level of support; they even generated some custom sample code for me.
I tried PDFBox, but found that it doesn't support the "Shrink to printable area" page scaling that you get with Acrobat. Not everyone will care about this feature, but it's essential for me.