package jp.crwdev.app.container.pdf;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import jp.crwdev.app.BufferedImageIO;
import jp.crwdev.app.constant.Constant;
import jp.crwdev.app.interfaces.IImageFileInfo;
import jp.crwdev.app.interfaces.IImageFileInfoList;
import jp.crwdev.app.interfaces.IImageFileWriter;
import jp.crwdev.app.interfaces.IImageFilter;
public class PdfImageFileWriter implements IImageFileWriter {
/** 出力先ファイル */
private File mOutputFile = null;
/** 画像フィルタ */
private IImageFilter mBaseFilter = null;
/** 処理中断フラグ */
private boolean mIsCancel = false;
private String mTitle = "";
private String mAuthor = "";
@SuppressWarnings("unused")
private String mTitleKana = "";
@SuppressWarnings("unused")
private String mAuthorKana = "";
@SuppressWarnings("unused")
private String mBookType = "book";
/**
* コンストラクタ
* @param title
* @param titleKana
* @param author
* @param authorKana
*/
public PdfImageFileWriter(String title, String titleKana, String author, String authorKana){
mTitle = title;
mTitleKana = titleKana;
mAuthor = author;
mAuthorKana = authorKana;
}
@Override
public boolean open(String filepath) {
File file = new File(filepath);
if(file.exists()){
if(!file.delete()){
return false;
}
}
mOutputFile = file;
return true;
}
@Override
public void setImageFilter(IImageFilter filter) {
mBaseFilter = filter;
}
@Override
public boolean write(IImageFileInfoList list, OnProgressListener listener) {
Document document = null;
PdfWriter writer = null;
File tempFile = null;
try {
tempFile = File.createTempFile("temp", "pdf");
int size = list.size();
float progressOffset = 100 / (float)size;
int index = 0;
for(int i=0; i<size; i++){
if(mIsCancel){
return false;
}
IImageFileInfo info = list.get(i);
BufferedImage image = null;
synchronized(info){
if(!info.isEnable()){
continue;
}
InputStream in = info.getInputStream();
if(in != null){
image = BufferedImageIO.read(in, info.isJpeg());
}
else{
image = info.getImage(false);
}
if(mBaseFilter != null){
image = mBaseFilter.filter(image, info.getFilterParam());
}
}
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
File file = File.createTempFile("temp", "jpg");
FileOutputStream outStream = new FileOutputStream(file);
BufferedImageIO.write(image, "jpeg", Constant.jpegQuality, outStream);
outStream.flush();
outStream.close();
if(document == null){
// Open前にサイズ指定しないと1ページ目に反映されない…
document = new Document(PageSize.A4, 0, 0, 0, 0);
document.setPageSize(new Rectangle(0, 0, imageWidth, imageHeight));
writer = PdfWriter.getInstance(document, new FileOutputStream(tempFile));
//writer.addViewerPreference(PdfName.DIRECTION, PdfName.R2L); // 右綴じ
document.open();
document.addTitle(mTitle);
document.addAuthor(mAuthor);
document.addCreationDate();
}
else{
document.setPageSize(new Rectangle(0, 0, imageWidth, imageHeight));
document.newPage();
}
Image jpeg2pdfImage = Image.getInstance(file.getAbsolutePath());
document.add(jpeg2pdfImage);
// TOC
String tocText = info.getTocText();
if(tocText != null && tocText.length() > 0){
addTocOutline(tocText, index + 1);
}
else if(index == 0){
addTocOutline("表紙", index + 1);
}
index++;
if(!file.delete()){
file.deleteOnExit();
}
if(listener != null){
listener.onProgress((int)((i+1)*progressOffset), null);
}
}
document.close();
document = null;
writer.close();
writer = null;
ArrayList<HashMap<String, Object>> outlines = getTocOutline();
PdfReader reader = new PdfReader(tempFile.getAbsolutePath());
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(mOutputFile.getAbsoluteFile()));
stamp.setOutlines(outlines);
stamp.addViewerPreference(PdfName.DIRECTION, PdfName.R2L); // 右綴じ
stamp.close();
stamp = null;
reader.close();
} catch (Exception e){
e.printStackTrace();
return false;
}
finally{
if(tempFile != null){
if(tempFile.exists()){
if(!tempFile.delete()){
tempFile.deleteOnExit();
}
}
tempFile = null;
}
if(document != null){
document.close();
document = null;
}
if(writer != null){
writer.close();
writer = null;
}
}
return true;
}
private ArrayList<HashMap<String, Object>> mTocOutline = new ArrayList<HashMap<String, Object>>();
private void addTocOutline(String title, int page){
// Reference http://itextpdf.com/examples/iia.php?id=140
if(mTocOutline == null){
mTocOutline = new ArrayList<HashMap<String, Object>>();
}
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Title", title);
map.put("Action", "GoTo");
map.put("Page", String.format("%d Fit", page));
mTocOutline.add(map);
}
private ArrayList<HashMap<String, Object>> getTocOutline(){
ArrayList<HashMap<String, Object>> outline = mTocOutline;
mTocOutline = null;
return outline;
}
@Override
public void close() {
if(mIsCancel){
if(mOutputFile != null){
if(mOutputFile.exists()){
mOutputFile.delete();
}
}
}
if(mOutputFile != null){
mOutputFile = null;
}
}
@Override
public void cancel() {
mIsCancel = true;
}
@Override
public String getSuffix() {
return ".pdf";
}
}