Printing landscape documents with Java on duplex mode - java

I've a JasperReports report to be printed on landscape mode on a duplex printer. On this I've to support PCL5 and PCL6 printing drivers.
Searching on the internet, I discovered the following code snippet to do this job:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Sides;
public class PrintingTest {
public static void main(String[] args) {
try {
//This are for configuration purpose
String orientation = "LANDSCAPE";
String duplexMode = "LONG_EDGE";
int pageOrientation = 0;
PrintRequestAttributeSet atr = new HashPrintRequestAttributeSet();
if ("Landscape".equals(orientation)) {
atr.add(OrientationRequested.LANDSCAPE);
pageOrientation = PageFormat.LANDSCAPE;
} else if ("Reverse_Landscape".equals(orientation)) {
atr.add(OrientationRequested.REVERSE_LANDSCAPE);
pageOrientation = PageFormat.REVERSE_LANDSCAPE;
} else {
atr.add(OrientationRequested.PORTRAIT);
pageOrientation = PageFormat.PORTRAIT;
}
if ("LONG_EDGE".equals(duplexMode)) {
atr.add(Sides.TWO_SIDED_LONG_EDGE);
} else {
atr.add(Sides.TWO_SIDED_SHORT_EDGE);
}
//Printing to the default printer
PrintService printer = javax.print.PrintServiceLookup
.lookupDefaultPrintService();
//Creating the printing job
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintService(printer);
Book book = new Book();
PageFormat pageFormat = printJob.defaultPage();
pageFormat.setOrientation(pageOrientation);
// Appending a exampledocument to the book
book.append(new ExampleDocument(), pageFormat);
// Appending another exampledocument to the book
book.append(new ExampleDocument(), pageFormat);
// Setting the Pageable to the printjob
printJob.setPageable(book);
try {
// Here a could show the print dialog
// printJob.printDialog(atr);
// Here I pass the previous defined attributes
printJob.print(atr);
} catch (Exception PrintException) {
PrintException.printStackTrace();
}
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
public static final int MARGIN_SIZE = 72;
private static class ExampleDocument implements Printable {
public int print(Graphics g, PageFormat pageFormat, int page) {
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pageFormat.getImageableX(),
pageFormat.getImageableY());
// Only on the first two documents...
if (page <= 1) {
// Prints using one inch margin
g2d.drawString("Printing page " + page + " - duplex...",
MARGIN_SIZE, MARGIN_SIZE);
return (PAGE_EXISTS);
}
return (NO_SUCH_PAGE);
}
}
}
This works fine on PCL6, but, when tested on PCL5, I noticed that LONG_EDGE and SHORT_EDGE rules are simple ignored. And that in both cases the job is sent as LONG_EDGE. This would not be a problem, except that Java AWT printing API resolves landscape printing by turning all pages 90º anti-clockwise causing the impression that it was printed on SHORT_EDGE mode.
Obs: I was able to print correctly with both configuration, SHORT_EDGE and LONG_EDGE, in portrait and in landscape, by using the SWT API. But I'm not able to convert the jasper printing request in a SWT compatible printing request.
My question is: has anybody ever confronted this situation? Which solution was given to it?
From my observation I've found these possible solutions:
Instead of letting the AWT turn the page and send a portrait print request, force it to send it as a landscape printing request;
Find a way to, when the page is in landscape mode, invert LONG_EDGE and SHORT_EDGE commands. Observe that for this one I would be obligated to correct the problem in which both are treated as LONG_EDGE requests.
Convert the JasperReports to use SWT printing API.

Not sure it helps but I had this issue 6 years ago and the only solution was to use the printer's (Xerox) capability to receive the printing directives through an .xpf file. Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xpif SYSTEM "xpif-v02012.dtd">
<xpif cpss-version="2.01" version="1.0" xml:lang="en">
<xpif-operation-attributes>
<job-name syntax="name" xml:lang="en" xml:space="preserve">job name</job-name>
<requesting-user-name syntax="name" xml:space="preserve">domain user</requesting-user-name>
</xpif-operation-attributes>
<job-template-attributes>
<copies syntax="integer">1</copies>
<finishings syntax="1setOf">
<value syntax="enum">3</value>
</finishings>
<job-recipient-name syntax="name" xml:lang="en-US" xml:space="preserve">domain user</job-recipient-name>
<job-save-disposition syntax="collection">
<save-disposition syntax="keyword">none</save-disposition>
</job-save-disposition>
<media-col syntax="collection">
<media-type syntax="keyword">stationery</media-type>
<media-hole-count syntax="integer">0</media-hole-count>
<media-color syntax="keyword">blue</media-color>
<media-size syntax="collection">
<x-dimension syntax="integer">21000</x-dimension>
<y-dimension syntax="integer">29700</y-dimension>
</media-size>
</media-col>
<orientation-requested syntax="enum">3</orientation-requested>
<sheet-collate syntax="keyword">collated</sheet-collate>
<sides syntax="keyword">one-sided</sides>
<x-side1-image-shift syntax="integer">0</x-side1-image-shift>
<y-side1-image-shift syntax="integer">0</y-side1-image-shift>
</job-template-attributes>
</xpif>
which was sent to the printer along with the file needed to be printed.

Related

How to get AnimationInfo from Apache POI Presentation

There is a class called AnimationInfo which supposed to give animation information from Presentation. But my bad luck I could not get it.
List<XSLFShape> shapes = slide.getShapes();
for (XSLFShape shape: shapes) {
//Need to get animation of this shape here
}
Can anyone help me on this ? Thanks.
PS: I am using 3.17 version of POI.
Given the addition of only detecting an animation, a sheet can be checked for a timing information which quite likely identifies the existence of an animation, i.e. you could get a false positive in case an animation was added and then removed again. Furthermore you need to check all slides, until an animation is found.
import java.io.FileInputStream;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordContainer;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.xslf.usermodel.XSLFSlide;
public class AnimCheck {
private static final int timingRecordPath[] = {
RecordTypes.ProgTags.typeID,
RecordTypes.ProgBinaryTag.typeID,
RecordTypes.BinaryTagData.typeID,
0xf144
};
public static void main(String[] args) throws Exception {
SlideShow<?,?> ppt = SlideShowFactory.create(new FileInputStream("no_anim.pptx"));
Slide<?,?> slide = ppt.getSlides().get(0);
boolean hasTiming;
if (slide instanceof XSLFSlide) {
XSLFSlide xsld = (XSLFSlide)slide;
hasTiming = xsld.getXmlObject().isSetTiming();
} else {
HSLFSlide hsld = (HSLFSlide)slide;
Record lastRecord = hsld.getSheetContainer();
boolean found = true;
for (int ri : timingRecordPath) {
lastRecord = ((RecordContainer)lastRecord).findFirstOfType(ri);
if (lastRecord == null) {
found = false;
break;
}
}
hasTiming = found;
}
ppt.close();
System.out.println(hasTiming);
}
}

JApplet lacking full functionality in browser

I have a Java JApplet that functions perfectly when eclipse runs it but dissapoints in a browser.
The applet is working fine in the browser up to the point at which the only JButton is pressed. At which point, something should happen, but, in the browser, nothing happens at all apart from the button shows it has been pressed. This doesn't happen when eclipse runs it.
Here is the code:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JTextArea;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
public class OverviewGenerator extends JApplet {
int state = 0;
JTextArea label = new JTextArea();
JButton button = new JButton();
String pluginYML;
YamlConfiguration yml = new YamlConfiguration();
String page;
public ActionListener buttonListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(state == 0) {
try {
pluginYML = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (HeadlessException e1) {
e1.printStackTrace();
} catch (UnsupportedFlavorException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
yml.loadFromString(pluginYML);
} catch (InvalidConfigurationException e1) {
e1.printStackTrace();
}
state = 1;
}else {
generatePage();
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
StringSelection strSel = new StringSelection(page);
clipboard.setContents(strSel, null);
state = 0;
}
refreshComponents();
}
};
/**
*
*/
private static final long serialVersionUID = 3470279389867972761L;
public void init() {
makeGui();
}
private void makeGui() {
label.setWrapStyleWord(true);
label.setLineWrap(true);
label.setBackground(Color.CYAN);
label.setEditable(false);
GridLayout layout = new GridLayout();
layout.setRows(2);
layout.setColumns(1);
getContentPane().setLayout(layout);
refreshComponents();
getContentPane().add(label);
getContentPane().add(button);
button.addActionListener(buttonListener);
}
private void refreshComponents() {
if(state==0) {
label.setText("Copy your plugin.yml into the clipboard then press done!");
button.setText("Done");
}else if(state == 1) {
label.setText("Now press the button to copy your template BukkitDev overview into your clipboard!");
button.setText("Copy");
}
}
private void generatePage() {
page = "";
page += "== "+yml.getString("name")+" ==\n";
if(yml.contains("description")) {
page += "\n//"+yml.getString("description")+"//\n\n\n";
}
if(yml.contains("commands")) {
page += "== Commands ==\n";
for(String command : yml.getConfigurationSection("commands").getKeys(false)) {
page += "\n=== "+command+" ===\n\n";
if(yml.contains("commands."+command+".description")) {
page += "//"+yml.getString("commands."+command+".description")+"//\n";
}
if(yml.contains("commands."+command+".usage")) {
page += "Usage: "+yml.getString("commands."+command+".usage")+"\n";
}
}
page += "\n";
}
if(yml.contains("permissions")) {
YamlConfiguration editedYml = new YamlConfiguration();
try {
editedYml.loadFromString(pluginYML.replace(".", "≠"));
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
ConfigurationSection permissions = editedYml.getConfigurationSection("permissions");
page += "== Permissions ==\n";
for(String permission : permissions.getKeys(false)) {
page += "\n=== "+permission.replace('≠', '.')+" ===\n\n";
if(editedYml.contains("permissions."+permission+".description")) {
page += "//"+editedYml.getString("permissions."+permission+".description").replace('≠', '.')+"//\n";
}
}
page += "\n\n\n";
}
page += "//Got any suggestions?//";
}
}
The code above is slightly outdated, I have added in the 'invoke later' code now! I am having trouble showing the Java console but I believe the error may be when the clipboard is accessed.
For security reasons, there are two ways that an applet can access the clip-board.
The applet is digitally signed by the developer, and trusted by the end user.
The applet uses the services of the JNLP API to access the clipboard. That is available in more recent JREs, Sun's 1.6.0_10+, for example.
There is potentially a 3rd way to get data to the applet that involves
having the user paste directly into an HTML form field
then use JS to transfer the data to the applet.
That could be done in a sand-boxed applet, and before the JRE that supports the JNLP API services. OTOH that would mean more clicks for the user, and more setting up.
//Got any suggestions?//
Beyond 'ask a more specific question' I might also suggest:
Enable the Java Console. That information is vital for debugging applets.
Read Copy in sand-boxed app. in 1.6.0_24+ for more details of the problem with clipboard access in applets, and strategies to copy data out of an applet using JS and other techniques.
Oracle released Java 6 Update 24 in February 2011 to remedy 21 vulnerabilities. As part of this security release, the ability to copy & paste from a computer's clipboard into a Java applet has been disabled.
To fix this issue there are 2 solutions:
Create a digital signature for the applet.
Work around: If you do not want to work with the digital signature, add to your java.policy file the following line: permission java.awt.AWTPermission "accessClipboard"
If you want to see an example of Java Applet working with a signed certificate you can looke here (the applet accepts paste action from clipboard which is not allowed to unsigned applets) : http://sqlinform.com/free_online_sw.html

How to get the single images of an mp4-Movie in Java

I want to do some image analysis on a video that's stored in .mp4 format. Therefore I need a way to just get the images of this movie in Java.
I goolged a lot and found some libraries like jcodec and jaad. BUT I wasn't able to get the things running with these libraries. And as I found out, there were examples (at least I found none) that showed my usecase.
Can you help me? Do you know any library that can do what I need and is running at least on Win7 64 bit.
Or do you know how to accomplish this with jcodec?
edit:
As I wrote, I tried it with jcodec. I found out how to get the data of a frame, but not how I can get it into something like a BufferedImage or so. I expect that these data isn't in a simple RGB format but in any compressed format or so. (Am I right with that?) I don't know to to decode this data.
You can get the data of a frame with jcodec as follows (at least as far as I understand this):
public static void main(String[] args) throws IOException, MP4DemuxerException {
String path = "videos/video-2011-09-21-20-07-21.mp4";
MP4Demuxer demuxer1 = new MP4Demuxer(new FileInput(new File(path)));
DemuxerTrack videoTrack = demuxer1.getVideoTrack();
Packet firstFrame = videoTrack.getFrames(1);
byte[] data = firstFrame.getData();
}
I also found the following:
http://code.google.com/p/jcodec/source/browse/trunk/src/test/java/org/jcodec/containers/mp4/DitherTest.java?r=70
But this isn't working (has compile errors) with the downloadable jar-package.
you could use jcodec(https://github.com/jcodec/jcodec) in the followinf program i am extracting frames from a video.
/*
* To extract frames from a mp4(avc) video
*
*/
package avc_frame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.jcodec.api.FrameGrab;
import org.jcodec.api.JCodecException;
public class Avc_frame {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException, JCodecException {
long time = System.currentTimeMillis();
for (int i = 50; i < 57; i++) {
BufferedImage frame = FrameGrab.getFrame(new File("/Users/jovi/Movies/test.mp4"), i);
ImageIO.write(frame, "bmp", new File("/Users/jovi/Desktop/frames/frame_"+i+".bmp"));
}
System.out.println("Time Used:" + (System.currentTimeMillis() - time)+" Milliseconds");
}
}
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FrameGrabber.Exception;
public class Read{
public static void main(String []args) throws IOException, Exception
{
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber("C:/Users/Digilog/Downloads/Test.mp4");
frameGrabber.start();
IplImage i;
try {
i = frameGrabber.grab();
BufferedImage bi = i.getBufferedImage();
ImageIO.write(bi,"png", new File("D:/Img.png"));
frameGrabber.stop();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Sending data to a printer in Java

The code below sends data to a printer however, while it reaches the printer queue it comes back with a Unable to convert PostScript file. I thought that this would be overcome by specifying the flavor but this is not the case
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.standard.PrinterName;
public class New1 {
public static void main(String[] args) {
try {
String s = "Hello";
// byte[] by = s.getBytes();
DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN;
PrintService pservice = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = pservice.createPrintJob();
Doc doc = new SimpleDoc(s, flavor, null);
job.print(doc, null);
} catch (PrintException e) {
e.printStackTrace();
}
}
}
Using only JPS you will have problems with Mac.
My suggestion is use Java 2 Print API + Java Print Service.
Java 2 Print API is something like 1990 style. To avoid to create your code using Java 2 Print API you could use PDFBox http://pdfbox.apache.org as a framework.
With PDFBox you could create a PDF document (http://pdfbox.apache.org/1.8/cookbook/documentcreation.html) but instead of save, print it using that code:
PrinterJob printJob = PrinterJob.getPrinterJob();
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
printJob.setPrintService(service);
document.silentPrint(printJob);
It works fine in my Mac.

Java Applet PDF printing

I am trying to build a java applet which prints a PDF file and sends it to a label printer rather than the default. I explored desktop.print but couldn't work out how to specify the printer.
This is the code I have, i've tried to look for solutions but have ended stuck. I have signed the applet and the error it gives me it just says application error 0
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.print.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
public class printPDF extends JApplet {
public void init(){
String uri = System.getProperty("user.home") + "\\jobbase\\print.pdf";
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new PrinterName("label", null));
aset.add(new Copies(1));
PrintService[] pservices =
PrintServiceLookup.lookupPrintServices(flavor, aset);
if (pservices.length > 0) {
DocPrintJob printJob = pservices[0].createPrintJob();
try{
FileInputStream fis = new FileInputStream(uri);
Doc doc = new SimpleDoc(fis, flavor, null);
try {
printJob.print(doc, aset);
} catch (PrintException e) {
System.err.println(e);
}
} catch(IOException ioe){
ioe.printStackTrace(System.out);
}
} else {
System.err.println("No suitable printers");
}
}
}
You can't just send the PDF to the printer unless you know it can understand it. Most of the time you need to rasterize it on the client. I write a blog article explaining the options at http://www.jpedal.org/PDFblog/2010/01/printing-pdf-files-from-java/
If you know the name of the printer you can achieve this. In one client I needed silent printing: if a printer named appprinter was present, I used it, if not I tried with the default. This worked out fine.
For printing I use ICEPDF.
Kate: thanks for the suggestion, honestly IcePDF is pretty straight forward, this example is included in the source code that you can download from the link above. In order to obtain the PrinterService (aka printer) needed you can delete all the user input requested by keyboard and just use the one with the name you want.
So, in version 5.0.5: [install-folder]/examples/printservices/PrintService.java
delete user selection of printservice: lines 106 to 155
add instead:
PrintService selectedService=null;
for (int j=0;j<services.length;j++) {
if ("myprintername".equalsIgnoreCase(services[j].getName())) {
selectedService=aux[j];
}
}
Hope now it is more useful.
Best regards.

Categories