Adjusting size of image to be printed on thermal printer - java

I want to print an image on thermal printer, but when I use this code, the image gets smaller. How can I change the size of the image that I'm going to print?
public void printPhoto() throws Exception {
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(new Copies(1));
pras.size();
PrintService pss[] = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.PNG, pras);
if (pss.length == 0)
throw new RuntimeException("No printer services available.");
PrintService ps = findPrintService("POS-58", pss);
System.out.println("Printing to " + ps);
DocPrintJob job = ps.createPrintJob();
FileInputStream fin = new FileInputStream("D:\\QRCODE\\test.png");
Doc doc = new SimpleDoc(fin, DocFlavor.INPUT_STREAM.PNG, null);
job.print(doc, pras);
fin.close();
}
Can anyone help me? This is for our school project. Thanks a lot.

I change my code to this
private static BufferedImage image;
public void PrintLogo(){
try {
image = ImageIO.read(new File("C:\\Users\\ADMIN\\Desktop\\logothermal.png"));
System.out.println(image.getWidth() + "x" + image.getHeight());
PrinterJob pj = PrinterJob.getPrinterJob();
PageFormat pf = pj.defaultPage();
Paper paper = pf.getPaper();
// 86X54mm
double width = fromCMToPPI(7.6);
double height = fromCMToPPI(3.4);
paper.setSize(width, height);
paper.setImageableArea(
fromCMToPPI(0.1),
fromCMToPPI(0.1),
width - fromCMToPPI(0.1),
height - fromCMToPPI(0.1));
pf.setOrientation(PageFormat.PORTRAIT);
pf.setPaper(paper);
PageFormat validatePage = pj.validatePage(pf);
System.out.println("Valid- " + dump(validatePage));
pj.setPrintable(new MyPrintable(), validatePage);
try {
pj.print();
} catch (PrinterException ex) {
ex.printStackTrace();
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
public static double fromPPItoCM(double dpi) {
return dpi / 72 / 0.393700787;
}
public static double fromCMToPPI(double cm) {
return toPPI(cm * 0.393700787);
}
public static double toPPI(double inch) {
return inch * 72d;
}
public static String dump(Paper paper) {
StringBuilder sb = new StringBuilder(64);
sb.append(paper.getWidth()).append("x").append(paper.getHeight())
.append("/").append(paper.getImageableX()).append("x").
append(paper.getImageableY()).append(" - ").append(paper
.getImageableWidth()).append("x").append(paper.getImageableHeight());
return sb.toString();
}
public static String dump(PageFormat pf) {
Paper paper = pf.getPaper();
return dump(paper);
}
public static class MyPrintable implements Printable {
#Override
public int print(Graphics graphics, PageFormat pageFormat,
int pageIndex) throws PrinterException {
System.out.println(pageIndex);
int result = NO_SUCH_PAGE;
if (pageIndex < 1) {
Graphics2D g2d = (Graphics2D) graphics;
System.out.println("[Print] " + dump(pageFormat));
double width = pageFormat.getImageableWidth();
double height = pageFormat.getImageableHeight()/2;
System.out.println("Print Size = " + fromPPItoCM(width) + "x" +
fromPPItoCM(height));
g2d.translate((int) pageFormat.getImageableX(),
(int) pageFormat.getImageableY());
Image scaled = null;
if (width > height) {
scaled = image.getScaledInstance((int)Math.round(width), -1,
Image.SCALE_SMOOTH);
} else {
scaled = image.getScaledInstance(-1, (int)Math.round(height),
Image.SCALE_SMOOTH);
}
g2d.drawImage(scaled, 0, 0, null);
result = PAGE_EXISTS;
}
return result;
}
}

Related

Printing a Multi-page JPanel

I'm nervous about asking this because I'm scared I'll get told off. I am trying to print a JPanel that is about 4 pages long. It could be more, the data is from a JDBC MySql query, that could end up being many more that 4. The JPanel I am trying to print is full of other JPanels (with competitors race details on them) that I have added via a ListArray..
Anyway, I have scoured all day through stackoverflow and have found may examples of code that I have tried to implement. The printable class only prints the first page, so I have tried to implement the pageable class, but I just can't seem to get it right. I have tried to implement the Book class but don't know how to add my JPanel to the book. I have looked here, here and many more (I'm only allowed to post 2 links).
Here is my current code (that I got off one of the answers that #madprogrammer gave) -
int printButton = JOptionPane.showOptionDialog(null, scrollPane, "Race Winners", JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE, // no Icon
null, //do not use a custom Icon
options, //the titles of buttons
options[0]); //default button title
if (printButton == 0) {
try {
printComponent(pane, true);
//printComponentToFile(pane, false);
} catch (PrinterException exp) {
exp.printStackTrace();
}
public static void printComponent(JComponent comp, boolean fill) throws PrinterException {
PrinterJob pjob = PrinterJob.getPrinterJob();
//pjob.setPageable(comp);
PageFormat pf = pjob.defaultPage();
pf.setOrientation(PageFormat.PORTRAIT);
PageFormat postformat = pjob.pageDialog(pf);
if (pf != postformat) {
//Set print component
//pjob.setPageable(comp);
pjob.setPrintable(new ComponentPrinter(comp, fill), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
}
public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.PORTRAIT);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()), (int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrinter cp = new ComponentPrinter(comp, fill);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrinter implements Printable, Pageable {
private Component comp;
private boolean fill;
int numPages;
PageFormat format;
public ComponentPrinter(Component comp, boolean fill) {
this.comp = comp;
this.fill = fill;
}
#Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
numPages = (int) Math.ceil(comp.getHeight() / format.getImageableY());
System.out.print(numPages);
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
g2.translate(format.getImageableX(), format.getImageableY());
//g2.translate(format.getImageableX(), format.getImageableY()- page_index*comp.getPreferredSize().height);
double width = (int) Math.floor(format.getImageableWidth());
double height = (int) Math.floor(format.getImageableHeight());
if (!fill) {
width = Math.min(width, comp.getPreferredSize().width);
height = Math.min(height, comp.getPreferredSize().height);
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
if (comp.getParent() == null) {
comp.addNotify();
}
comp.validate();
comp.doLayout();
comp.printAll(g2);
if (comp.getParent() != null) {
comp.removeNotify();
}
return Printable.PAGE_EXISTS;
}
#Override
public int getNumberOfPages() {
// TODO Auto-generated method stub
return numPages;
}
#Override
public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
return format;
}
#Override
public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
// TODO Auto-generated method stub
return this;
}
}
This all works, but only prints the first page. I would REALLY appreciate a nudge in the right direction with this as I'm stumped. TIA :-)
This is how you print a Component (JPanel) on multiple pages:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.*;
import javax.swing.RepaintManager;
public class PrintMultiPageUtil implements Printable, Pageable {
private Component componentToBePrinted;
private PageFormat format;
private int numPages;
public PrintMultiPageUtil(Component componentToBePrinted) {
this.componentToBePrinted = componentToBePrinted;
// get total space from component
Dimension totalSpace = this.componentToBePrinted.getPreferredSize();
// calculate for DIN A4
format = PrinterJob.getPrinterJob().defaultPage();
numPages = (int) Math.ceil(totalSpace .height/format.getImageableHeight());
}
public void print() {
PrinterJob printJob = PrinterJob.getPrinterJob();
// show page-dialog with default DIN A4
format = printJob.pageDialog(printJob.defaultPage());
printJob.setPrintable(this);
printJob.setPageable(this);
if (printJob.printDialog())
try {
printJob.print();
} catch(PrinterException pe) {
System.out.println("Error printing: " + pe);
}
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
if ((pageIndex < 0) | (pageIndex >= numPages)) {
return(NO_SUCH_PAGE);
} else {
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
disableDoubleBuffering(componentToBePrinted);
componentToBePrinted.paint(g2d);
enableDoubleBuffering(componentToBePrinted);
return(PAGE_EXISTS);
}
}
public static void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public static void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
#Override
public int getNumberOfPages() {
// TODO Auto-generated method stub
return numPages;
}
#Override
public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
return format;
}
#Override
public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
// TODO Auto-generated method stub
return this;
}
}
numPages
I changed the expression for numPages to:
(int) Math.ceil(page.height/format.getImageableHeight())
This divides the total height (height of the jpanel) through the height of one page, thus calculating the number of all pages.
g2d.translate
I did the following change: In this line:
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
Changed componentToBePrinted.getPreferredSize().height to pageFormat.getImageableHeight(). A positive value for the first or the second parameter of g2d.translate moves the graphic to the right or down respectively.
.getImageableX() and .getImageableY() help position the graphic so that it doesn't overlap with the padding.
For pageIndex greater than 0, - pageIndex * pageFormat.getImageableHeight() moves the image pageIndex-times the page-height to the top. So the area, that the pageIndex refers to is printed.
original broken source:: https://community.oracle.com
Here is my original answer.

Printing a jframe in java

I would like to print a jframe when clicking a button.
So i tried this code. If I click the print button, I get a printer dialog and when I tell it to print, it just prints a blank document, i don't know why. Any help?
public static class Printer implements Printable {
final Component comp;
public Printer(Component comp){
this.comp = comp;
}
#Override
public int print(Graphics g, PageFormat format, int page_index)
throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
// get the bounds of the component
Dimension dim = comp.getSize();
double cHeight = dim.getHeight();
double cWidth = dim.getWidth();
// get the bounds of the printable area
double pHeight = format.getImageableHeight();
double pWidth = format.getImageableWidth();
double pXStart = format.getImageableX();
double pYStart = format.getImageableY();
double xRatio = pWidth / cWidth;
double yRatio = pHeight / cHeight;
Graphics2D g2 = (Graphics2D) g;
g2.translate(pXStart, pYStart);
g2.scale(xRatio, yRatio);
comp.paint(g2);
return Printable.PAGE_EXISTS;
}
}
and in the button action performed
JFrame yourComponent = new ODietListJFrame();
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat preformat = pjob.defaultPage();
preformat.setOrientation(PageFormat.LANDSCAPE);
PageFormat postformat = pjob.pageDialog(preformat);
//If user does not hit cancel then print.
if (preformat != postformat) {
//Set print component
pjob.setPrintable(new Printer(yourComponent), postformat);
if (pjob.printDialog()) {
try {
pjob.print();
} catch (PrinterException ex) {
Logger.getLogger(ODietListJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Thanks for help.

Visual signature with pdfbox 1.8.8

I'm trying to produce PDF with visual signature and pdfbox. I have two streams and it seems that pdfbox can deal only with files. I didn't manage to make it work without three temporary files. I can see from here that API has changed, but still it deals with files.
public void signPdf(InputStream originalPdf, OutputStream signedPdf,
InputStream image, float x, float y,
String name, String location, String reason) {
File temp = null;
File temp2 = null;
File scratchFile = null;
RandomAccessFile randomAccessFile = null;
OutputStream tempOut = null;
InputStream tempIn = null;
try {
/* Copy original to temporary file */
temp = File.createTempFile("signed1", ".tmp");
tempOut = new FileOutputStream(temp);
copyStream(originalPdf, tempOut);
tempOut.close();
/* Read temporary file to second temporary file and stream */
tempIn = new FileInputStream(temp);
temp2 = File.createTempFile("signed2", ".tmp");
tempOut = new FileOutputStream(temp2);
copyStream(tempIn, tempOut);
tempIn.close();
tempIn = new FileInputStream(temp2);
scratchFile = File.createTempFile("signed3", ".bin");
randomAccessFile = new RandomAccessFile(scratchFile, "rw");
/* Read temporary file */
PDDocument document = PDDocument.load(temp, randomAccessFile);
document.getCurrentAccessPermission().setCanModify(false);
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName(name);
signature.setLocation(location);
signature.setReason(reason);
signature.setSignDate(Calendar.getInstance());
PDVisibleSignDesigner signatureDesigner = new PDVisibleSignDesigner(
document, image, document.getNumberOfPages());
signatureDesigner.xAxis(250).yAxis(60).zoom(-90).signatureFieldName("signature");
PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
.buildSignature();
SignatureOptions options = new SignatureOptions();
options.setVisualSignature(signatureProperties);
document.addSignature(signature, dataSigner, options);
/* Sign */
document.saveIncremental(tempIn, tempOut);
document.close();
tempIn.close();
/* Copy temporary file to an output stream */
tempIn = new FileInputStream(temp2);
copyStream(tempIn, signedPdf);
} catch (IOException e) {
logger.error("PDF signing failure", e);
} catch (COSVisitorException e) {
logger.error("PDF creation failure", e);
} catch (SignatureException e) {
logger.error("PDF signing failure", e);
} finally {
closeStream(originalPdf);
closeStream(signedPdf);
closeStream(randomAccessFile);
closeStream(tempOut);
deleteTempFile(temp);
deleteTempFile(temp2);
deleteTempFile(scratchFile);
}
}
private void deleteTempFile(File tempFile) {
if (tempFile != null && tempFile.exists() && !tempFile.delete()) {
tempFile.deleteOnExit();
}
}
private void closeStream(Closeable is) {
if (is!= null) {
try {
is.close();
} catch (IOException e) {
logger.error("failure", e);
}
}
}
private void copyStream(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int c;
while ((c = is.read(buffer)) != -1) {
os.write(buffer, 0, c);
}
is.close();
}
Apart from file madness I don't see any text on the signature. This is how result looks like:
and this is how it looks, when I do similar thing with itext library
Why name, location and reason missing from the visual signature representation? How can I fix that?
Why name, location and reason missing from the visual signature representation?
They are not there because they are not drawn.
The default way of iText to represent a visualized signature is by adding those information to the visualization.
The default way of PDFBox' PDVisibleSigBuilder to represent a visualized signature is without such information.
Neither is wrong or right, both merely are defaults.
The canonical place where people shall look for such information is the signature panel after all.
How can I fix that?
The actual contents of the signature visualization are created by a PDVisibleSigBuilder instance during signatureProperties.buildSignature():
public void buildSignature() throws IOException
{
PDFTemplateBuilder builder = new PDVisibleSigBuilder();
PDFTemplateCreator creator = new PDFTemplateCreator(builder);
setVisibleSignature(creator.buildPDF(getPdVisibleSignature()));
}
Thus, by replacing
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
.buildSignature();
in your code by
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner);
PDFTemplateBuilder builder = new ExtSigBuilder();
PDFTemplateCreator creator = new PDFTemplateCreator(builder);
signatureProperties.setVisibleSignature(creator.buildPDF(signatureProperties.getPdVisibleSignature()));
for a customized version ExtSigBuilder of this PDVisibleSigBuilder class, you can draw anything you want there, e.g.:
class ExtSigBuilder extends PDVisibleSigBuilder
{
String fontName;
public void createImageForm(PDResources imageFormResources, PDResources innerFormResource,
PDStream imageFormStream, PDRectangle formrect, AffineTransform affineTransform, PDJpeg img)
throws IOException
{
super.createImageForm(imageFormResources, innerFormResource, imageFormStream, formrect, affineTransform, img);
PDFont font = PDType1Font.HELVETICA;
fontName = getStructure().getImageForm().getResources().addFont(font);
logger.info("Added font to image form: " + fontName);
}
public void injectAppearanceStreams(PDStream holderFormStream, PDStream innterFormStream, PDStream imageFormStream,
String imageObjectName, String imageName, String innerFormName, PDVisibleSignDesigner properties)
throws IOException
{
super.injectAppearanceStreams(holderFormStream, innterFormStream, imageFormStream, imageObjectName, imageName, innerFormName, properties);
String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + " Do Q\n";
String text = "BT /" + fontName + " 10 Tf (Hello) Tj ET\n";
appendRawCommands(getStructure().getImageFormStream().createOutputStream(), imgFormComment + text);
logger.info("Added text commands to image form: " + text);
}
}
writes "Hello" in Helvetica at size 10 atop the lower left of the image form (the form actually displaying something).
PS: In my opinion the object oriented structure behind this should be completely overhauled.
Display the text over the signatory some time it doesn't look nice. For me, I create new image base on the text that I want to display. And merge it with the signatory image. I can add background for signatory image (company name watermark)
Here is the code create new signatory image with text and background:
public class ImageSignatory {
public static void main(String[] args) {
DateFormat df = new SimpleDateFormat("MM.dd.yyyy");
Date today = Calendar.getInstance().getTime();
String reportDate = df.format(today);
String text = "Signature eletronic Company AA DUC NGUYEN - Date " + reportDate;
String background = "background.png";
String signImage = "sign.jpg";
String textImage = createImageFromText(text);
String imageResultURL = null ;
try {
String mergedImage = mergeTwoImage(signImage, textImage);
imageResultURL = addBackgroundToImage(background, mergedImage);
} catch (Exception ex) {
}
}
public static String StringDivider(String s) {
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
sb.replace(i, i + 1, "\n");
}
return sb.toString();
}
public static BufferedImage toBufferedImage(Image img) {
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
return bimage;
}
public static String addBackgroundToImage(String backgroundPATH, String imagePath) {
try {
String imageResult = "result.jpg";
Image backgroundImage = ImageIO.read(new File(backgroundPATH));
int width = backgroundImage.getWidth(null);
int height = backgroundImage.getHeight(null);
Image signAndText = ImageIO.read(new File(imagePath));
signAndText = signAndText.getScaledInstance(width, height, Image.SCALE_SMOOTH);
signAndText = toBufferedImage(signAndText);
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g2 = combined.getGraphics();
g2.drawImage(backgroundImage, 0, 0, null);
g2.drawImage(signAndText, 0, 0, null);
g2.dispose();
ImageIO.write(combined, "JPG", new File(imageResult));
return imageResult;
} catch (IOException ex) {
return null;
}
}
public static String mergeTwoImage(String first, String second) {
try {
String tempFileName = "merged_image.png";
Image signatoryImage = ImageIO.read(new File(first));
Image addtionalTextImage = ImageIO.read(new File(second));
float ratio = (float) signatoryImage.getWidth(null) / (float) addtionalTextImage.getWidth(null);
addtionalTextImage = addtionalTextImage.getScaledInstance((int) (ratio * (float) addtionalTextImage.getWidth(null)), (int) (ratio * (float) addtionalTextImage.getHeight(null)), Image.SCALE_SMOOTH);
addtionalTextImage = toBufferedImage(addtionalTextImage);
BufferedImage combinedTemp = new BufferedImage(signatoryImage.getWidth(null), signatoryImage.getHeight(null) + (int) (ratio * (float) addtionalTextImage.getHeight(null)), BufferedImage.TYPE_INT_ARGB);
Graphics g = combinedTemp.getGraphics();
g.drawImage(signatoryImage, 0, 0, null);
g.drawImage(addtionalTextImage, 0, signatoryImage.getHeight(null), null);
g.dispose();
ImageIO.write(combinedTemp, "PNG", new File(tempFileName));
return tempFileName;
} catch (IOException ex) {
return null;
}
}
public static String createImageFromText(String text) {
String tempFileName = "text.png";
text = StringDivider(text);
String[] textParts = text.split("\n");
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 48);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = 0;
for (String textPart : textParts) {
int tempWidth = fm.stringWidth(textPart);
if (tempWidth > width) {
width = tempWidth;
}
}
width += 10;
int oneLineHeight = fm.getHeight();
int height = (oneLineHeight) * textParts.length;
g2d.dispose();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setFont(font);
fm = g2d.getFontMetrics();
g2d.setColor(Color.BLACK);
int index = 0;
for (String textPart : textParts) {
g2d.drawString(textPart, 5, (oneLineHeight) * index + fm.getAscent());
index++;
}
g2d.dispose();
try {
ImageIO.write(img, "PNG", new File(tempFileName));
} catch (IOException ex) {
return null;
}
return tempFileName;
}
public static void removeFile(String fileName) {
try {
File file = new File(fileName);
file.delete();
} catch (Exception ex) {
}
}
}

Orientation sets only for first page in PDF printing - java

I'm using PDFRenderer.jar and this is the method i'm using to set print format,
private void initialize(byte[] pdfContent, String jobName) throws IOException, PrinterException {
ByteBuffer bb = ByteBuffer.wrap(pdfContent);
// Create PDF Print Page
PDFFile pdfFile = new PDFFile(bb);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job
pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
pf.setOrientation(PageFormat.PORTRAIT);
pjob.setJobName(jobName);
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
// to remove margins
Paper paper = new Paper();
paper.setSize(paper.getWidth(), paper.getHeight());
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
pf.setPaper(paper);
}
The issue is, orientation PORTRAIT sets only to the first page of the pdf,second page comes in REVERSE_LANDSCAPE which I haven't set from the code.
Any ideas?
Finaly , I found it
We cannot set print formats only from setting attributes to java.awt.print.PageFormat , we have to overide print(Graphics g, PageFormat format, int index) method in java.awt.print.Printable.This make the file print in pdf format(text and alignments).
Therefore this is the overridden print method,
public int print(Graphics g, PageFormat format, int index) throws PrinterException {
int pagenum = index + 1;
if ((pagenum >= 1) && (pagenum <= file.getNumPages())) {
Graphics2D g2 = (Graphics2D) g;
PDFPage page = file.getPage(pagenum);
// fit the PDFPage into the printing area
Rectangle imageArea = new Rectangle((int) format.getImageableX(), (int) format.getImageableY(),
(int) format.getImageableWidth(), (int) format.getImageableHeight());
g2.translate(0, 0);
PDFRenderer pgs = new PDFRenderer(page, g2, imageArea, null, null);
try {
page.waitForFinish();
pgs.run();
} catch (InterruptedException ie) {
// nothing to do
}
return PAGE_EXISTS;
} else {
return NO_SUCH_PAGE;
}
}
So,here is full code for print pdf (for printers doesn't support direct printing) using pdf renderer,
public static void main(String[] args) throws IOException, PrinterException {
if (args.length != 1) {
System.err.println("The first parameter must have the location of the PDF file to be printed");
}
FileInputStream fis = new FileInputStream(new File("x.pdf"));//file path
PrintPdf printPDFFile = new PrintPdf(fis, "Test Print PDF");
printPDFFile.print();
}
public static PrintService setPrintService(String argPrintServiceName) throws PrinterException {
PrintService psr = null;
PrintService[] printServices = PrinterJob.lookupPrintServices();
int i;
for (i = 0; i < printServices.length; i++) {
if (printServices[i].getName().equalsIgnoreCase(argPrintServiceName)) {
psr = printServices[i];
break;
}
}
if (i == printServices.length) {
throw new PrinterException("Invalid print service name: " + argPrintServiceName);
}
return psr;
}
/**
* Constructs the print job based on the input stream
*
* #param inputStream
* #param jobName
* #throws IOException
* #throws PrinterException
*/
public PrintPdf(InputStream inputStream, String jobName) throws IOException, PrinterException {
byte[] pdfContent = new byte[inputStream.available()];
inputStream.read(pdfContent, 0, inputStream.available());
initialize(pdfContent, jobName);
}
/**
* Initializes the job
*
* #param pdfContent
* #param jobName
* #throws IOException
* #throws PrinterException
*/
private void initialize(byte[] pdfContent, String jobName) throws IOException, PrinterException {
ByteBuffer bb = ByteBuffer.wrap(pdfContent);
/* Create PDF Print Page*/
PDFFile pdfFile = new PDFFile(bb);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
/* Create Print Job */
pjob = PrinterJob.getPrinterJob();
pf = PrinterJob.getPrinterJob().defaultPage();
pf.setOrientation(PageFormat.PORTRAIT);
pjob.setJobName(jobName);
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
/* to remove margins */
Paper paper = new Paper();
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
pf.setPaper(paper);
}
public void print() throws PrinterException {
// Send print job to default printer
pjob.print();
}
/**
* Class that actually converts the PDF file into Printable format
*/
class PDFPrintPage implements Printable {
private PDFFile file;
PDFPrintPage(PDFFile file) {
this.file = file;
}
public int print(Graphics g, PageFormat format, int index) throws PrinterException {
int pagenum = index + 1;
if ((pagenum >= 1) && (pagenum <= file.getNumPages())) {
Graphics2D g2 = (Graphics2D) g;
PDFPage page = file.getPage(pagenum);
// fit the PDFPage into the printing area
Rectangle imageArea = new Rectangle((int) format.getImageableX(),(int)format.getImageableY(),(int) format.getImageableWidth(), (int) format.getImageableHeight());
g2.translate(0, 0);
PDFRenderer pgs = new PDFRenderer(page, g2, imageArea, null, null);
try {
page.waitForFinish();
pgs.run();
} catch (InterruptedException ie) {
// nothing to do
}
return PAGE_EXISTS;
} else {
return NO_SUCH_PAGE;
}
}
}
Thanks if any one who tried to find the bug and my senior engineer for giving his support to find this.

How would I suppress the print dialog in this example?

private void printCard() {
PrinterJob printjob = PrinterJob.getPrinterJob();
printjob.setJobName("Label");
Printable printable = new Printable() {
public int print(Graphics pg, PageFormat pf, int pageNum) {
if (pageNum > 0) {
return Printable.NO_SUCH_PAGE;
}
Dimension size = jLayeredPane2.getSize();
BufferedImage bufferedImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
jLayeredPane2.print(bufferedImage.getGraphics());
Graphics2D g2 = (Graphics2D) pg;
g2.translate(pf.getImageableX(), pf.getImageableY());
g2.drawImage(bufferedImage, 0, 0, (int) pf.getWidth(), (int) pf.getHeight(), null);
return Printable.PAGE_EXISTS;
}
};
Paper paper = new Paper();
paper.setImageableArea(0, 0, 153, 243);
paper.setSize(243, 154);
PageFormat format = new PageFormat();
format.setPaper(paper);
format.setOrientation(PageFormat.LANDSCAPE);
printjob.setPrintable(printable, format);
if (printjob.printDialog() == false)
return;
try {
printjob.print();
} catch (PrinterException ex) {
System.out.println("NO PAGE FOUND." + ex);
}
}
From what I see in your code, you call if (printjob.printDialog() == false). This will always try to show the native printer properties dialog. The boolean return value is based on whether the user clicks OK or cancels out of the dialog. If you want to suppress the dialog, remove that if block, as the printing work that you want to perform is done via the printjob.print() call.

Categories

Resources