package bd.amazed.docscissors.doc; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import javax.swing.ProgressMonitor; import org.rr.commons.mufs.IResourceHandler; import org.rr.jeborker.app.JeboorkerConstants; import org.rr.pm.image.ImageUtils; import bd.amazed.docscissors.model.Bundle; import bd.amazed.docscissors.model.PageGroup; import bd.amazed.docscissors.model.PageRectsMap; import com.itextpdf.text.DocumentException; public abstract class DocumentCropper { private JDocumentDecoderPanel pdfDecoder; protected boolean isCancel; protected IResourceHandler mainFile; public DocumentCropper(IResourceHandler file) { if (file == null) { throw new IllegalArgumentException("PDFCropper does not accept null file."); } this.mainFile = file; } public static DocumentCropper getCropper(IResourceHandler file) { if(JeboorkerConstants.SUPPORTED_MIMES.MIME_PDF.getMime().equals(file.getMimeType(true))) { return new PdfCropper(file); } else if(JeboorkerConstants.SUPPORTED_MIMES.MIME_CBZ.getMime().equals(file.getMimeType(true)) || JeboorkerConstants.SUPPORTED_MIMES.MIME_CBR.getMime().equals(file.getMimeType(true))) { return new CbxCropper(file); } throw new IllegalArgumentException("File type " + file + " not supported"); } public abstract DocumentInfo getDocumentInfo() throws DocumentException, IOException; public void cancel() { isCancel = true; } public abstract void crop(DocumentInfo docFile, File targetFile, PageRectsMap pageRectsMap, int viewWidth, int viewHeight, ProgressMonitor progressMonitor) throws IOException, DocumentException; public BufferedImage getNormalizedImage(DocumentInfo docFile, PropertyChangeListener listener, PageGroup pageGroup) throws ScissorsDocumentException { BufferedImage image = getImage(docFile, listener, pageGroup); image = ImageUtils.crop(image, new Rectangle((int)docFile.getNormalizedWidth(),(int) docFile.getNormalizedHeight()), Color.WHITE); return image; } public BufferedImage getImage(DocumentInfo docFile, PropertyChangeListener listener, PageGroup pageGroup) throws ScissorsDocumentException { int endPage = pageGroup.getLastPage(); JDocumentDecoderPanel docDecoder = getDocumentDecoder(docFile); BufferedImage lastPage = docDecoder.getPageAsImage(endPage); if (lastPage != null) { listener.propertyChange(new PropertyChangeEvent(this, "message", null, Bundle.getString("PdfCropper.stacking") + " " + pageGroup)); lastPage = new BufferedImage(lastPage.getWidth(), lastPage.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) lastPage.getGraphics(); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, lastPage.getWidth(), lastPage.getHeight()); float alpha = 0.5f; int type = AlphaComposite.SRC_OVER; AlphaComposite composite = AlphaComposite.getInstance(type, alpha); g2d.setComposite(composite); int pageCount = pageGroup.getPageCount(); for (int iPageInGroup = pageCount - 1; iPageInGroup >= 0 && !isCancel; iPageInGroup--) { int i = pageGroup.getPageNumberAt(iPageInGroup); int percentageDone = (100 * (pageCount - iPageInGroup)) / pageCount; listener.propertyChange(new PropertyChangeEvent(this, "progress", null, percentageDone)); BufferedImage pageImage = getDocumentDecoder(docFile).getPageAsImage(i); if (pageImage != null) { g2d.drawImage(pageImage, 0, 0, null); } } } return lastPage; } private JDocumentDecoderPanel getDocumentDecoder(DocumentInfo docFile) throws ScissorsDocumentException { if (pdfDecoder == null) { pdfDecoder = new JDocumentDecoderPanel(); try { pdfDecoder.openPdfFile(docFile); } catch (RuntimeException ex) { if (ex.toString().contains("bouncy")) { // hah, stupid way of doing this, but what can i do if library // is throwing RuntimeException :( throw new ScissorsDocumentException("PDF is encrypted or password protected.\nTry to create an unencrypted pdf first using some other tool."); } } } return pdfDecoder; } }