複数のJPEGファイルを一つのPDFファイルに変換する(Java)
複数のJPEGファイルを一つのPDFファイルに変換する事のできるJavaのソースコードです。クラスになっていますのでそのまま使用できます。
ソースコード
5年以上前に作成した古いコードで私すら覚えていないのですが、何かのお役に立てると嬉しいです。
package in.papy.camera2pdf_plus; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Locale; public class jpeg2pdf { // 作成ソフト private String STR_CREATOR = "Camera2PDF ver0.1"; // メイン処理 public void run(StringList Files,String SaveName){ int ObjectIndex = 0; int ObjectPosArray[] = new int[10 * Files.size()]; FileOutputStream AStream = null; StringList pages_info = new StringList(); // page情報配列 try{ AStream = new FileOutputStream(SaveName,false); /* PDFヘッダ */ AStream.write("%PDF-1.4\n".getBytes()); /* Catalog */ ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write((String.format("%d 0 obj\n",ObjectIndex+1)).getBytes()); AStream.write("<<\n".getBytes()); AStream.write("/Type /Catalog\n".getBytes()); AStream.write("/Pages 2 0 R\n".getBytes()); AStream.write("/OpenAction [3 0 R /XYZ -32768 -32768 1 ]\n".getBytes()); // View Option (100%) AStream.write(">>\n".getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex++; // /Type /Pages 用に先にインクリメント ObjectIndex++; for (int i=0;i < Files.size();i++){ // JPEG情報(1:Height 2:width 3:colormap 4:filesize) StringList jpeg_detail = new StringList(); if (GetJPEGSize(Files.get(i),jpeg_detail) == false){ throw new Exception("Error : GetJPEGSize()"); } /* Kids Page */ pages_info.add(ObjectIndex+1); ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write(String.format("%d 0 obj\n",ObjectIndex+1).getBytes()); AStream.write("<<\n".getBytes()); AStream.write("/Type /Page\n".getBytes()); AStream.write("/Parent 2 0 R\n".getBytes()); AStream.write("/Resources\n".getBytes()); AStream.write("<<\n".getBytes()); AStream.write(String.format("/XObject << /Im0 %d 0 R >>\n",ObjectIndex+2).getBytes()); AStream.write("/ProcSet [ /PDF /ImageC ]\n".getBytes()); AStream.write(">>\n".getBytes()); AStream.write(String.format("/MediaBox [ 0 0 %d %d ]\n",Integer.parseInt(jpeg_detail.get(1)),Integer.parseInt(jpeg_detail.get(0))).getBytes()); AStream.write(String.format("/Contents %d 0 R\n",ObjectIndex+3).getBytes()); AStream.write(">>\n".getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex++; /* XObject Resource */ ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write(String.format("%d 0 obj\n",ObjectIndex+1).getBytes()); AStream.write("<<\n".getBytes()); AStream.write("/Type /XObject\n".getBytes()); AStream.write("/Subtype /Image\n".getBytes()); AStream.write("/Name /Im0\n".getBytes()); AStream.write(String.format("/Width %d\n",Integer.parseInt(jpeg_detail.get(1))).getBytes()); AStream.write(String.format("/Height %d\n",Integer.parseInt(jpeg_detail.get(0))).getBytes()); AStream.write("/BitsPerComponent 8\n".getBytes()); AStream.write("/Filter [/DCTDecode]\n".getBytes()); if (Integer.parseInt(jpeg_detail.get(2)) == 3) AStream.write("/ColorSpace /DeviceRGB\n".getBytes()); else { AStream.write("/ColorSpace /DeviceCMYK\n".getBytes()); AStream.write("/Decode[1 0 1 0 1 0 1 0]\n".getBytes()); /* Photoshop CMYK (NOT BIT) */ } AStream.write(String.format("/Length %d >>\n",Integer.parseInt(jpeg_detail.get(3))).getBytes()); AStream.write("stream\n".getBytes()); if (CopyStream(Files.get(i),AStream) == false) { throw new Exception("Error : CopyStream()"); } AStream.write("endstream\n".getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex++; /* Contents Stream & Object */ ObjectIndex = Write_ContentsObject(AStream,ObjectPosArray,ObjectIndex,Integer.parseInt(jpeg_detail.get(1)),Integer.parseInt(jpeg_detail.get(0))); } /* Parent Pages */ ObjectPosArray[1] = (int)AStream.getChannel().position(); AStream.write("2 0 obj\n".getBytes()); AStream.write("<<\n".getBytes()); AStream.write("/Type /Pages\n".getBytes()); AStream.write("/Kids [".getBytes()); for (int j=0;j<pages_info.size();j++){ AStream.write(String.format(" %d 0 R",Integer.parseInt(pages_info.get(j))).getBytes()); } AStream.write(" ]\n".getBytes()); AStream.write(String.format("/Count %d\n",pages_info.size()).getBytes()); AStream.write(">>\n".getBytes()); AStream.write("endobj\n".getBytes()); // 最初にインクリメント済みなのでコメント //ObjectIndex++; // ソフト情報 ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write(String.format("%d 0 obj\n",ObjectIndex+1).getBytes()); AStream.write("<<\n".getBytes()); AStream.write(String.format("/Producer (PDFDesigner for Android)\n",ObjectIndex+1).getBytes()); // 日本語のみ日付を設定。 if (Locale.JAPAN.equals(Locale.getDefault())) { AStream.write(String.format("/CreationDate (D:%s+09'00')\n",utility.getSysdate()).getBytes()); AStream.write(String.format("/ModDate (D:%s+09'00')\n",utility.getSysdate()).getBytes()); } AStream.write(String.format("/Creator (%s)\n",STR_CREATOR).getBytes()); AStream.write(">>\n".getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex++; /* CrossReferenceTable */ ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); Write_CrossReferenceTable(AStream,ObjectPosArray,(int)ObjectIndex); /* trailer */ AStream.write("trailer\n".getBytes()); AStream.write("<<\n".getBytes()); AStream.write(String.format("/Size %d\n",ObjectIndex+1).getBytes()); AStream.write("/Root 1 0 R\n".getBytes()); AStream.write(String.format("/Info %d 0 R\n",ObjectIndex).getBytes()); AStream.write(">>\n".getBytes()); AStream.write("startxref\n".getBytes()); AStream.write(String.format("%d\n",ObjectPosArray[ObjectIndex]).getBytes()); AStream.write("%%EOF\n".getBytes()); AStream.close(); }catch(Exception e){ e.printStackTrace(); }finally{ if (AStream != null){ try { AStream.close(); }catch(Exception e){ e.printStackTrace(); } } } } // ******************************** // Word値の取得 // ******************************** private int GetWord(byte hi,byte low){ return ((hi & 0xFF) << 8) + (low & 0xFF); } // ******************************** // JPEGファイルのコピー // ******************************** private boolean CopyStream(String OpenName,FileOutputStream output)throws Exception{ FileInputStream AStream = null; byte BYTE[]; try { AStream = new FileInputStream(OpenName); BYTE = new byte[(int)AStream.getChannel().size()]; AStream.read(BYTE, 0, (int)AStream.getChannel().size()); output.write(BYTE); }catch(Exception e){ e.printStackTrace(); return false; }finally{ if (AStream!=null) AStream.close(); } return true; } // ******************************** // JPEGファイルからHeight/Width/ColorMapの取得 // ******************************** private boolean GetJPEGSize(String OpenName,StringList obj)throws Exception{ byte WORD[] = new byte[2]; byte BYTE[] = new byte[2]; FileInputStream Stream = null; try { Stream = new FileInputStream(OpenName); /* JFIF(0xFFD8) */ if (Stream.read(WORD, 0, 2)< 1) return false; if (!(((WORD[0] & 0xFF) == 0xFF) && ((WORD[1] & 0xFF) == 0xD8))) return false; while (true){ if (Stream.read(WORD, 0, 2)< 1) return false; // Normal(0xFFC0)/Progressive (0xFFC2) if ((((WORD[0] & 0xFF) == 0xFF) && ((WORD[1] & 0xFF) == 0xC0)) || (((WORD[0] & 0xFF) == 0xFF) && ((WORD[1] & 0xFF) == 0xC2))){ // Skip Segment Length & Sample Stream.skip(3); // Height if (Stream.read(WORD,0, 2)< 1) return false; obj.add(GetWord(WORD[0],WORD[1])); // Width if (Stream.read(WORD,0, 2)< 1) return false; obj.add(GetWord(WORD[0],WORD[1])); // ColorMode if (Stream.read(BYTE,0, 1)< 1) return false; obj.add(BYTE[0] & 0xFF); // FileSize obj.add((int)Stream.getChannel().size()); return true; }else if ((((WORD[0] & 0xFF) == 0xFF) && ((WORD[1] & 0xFF) == 0xFF)) || (((WORD[0] & 0xFF) == 0xFF) && ((WORD[1] & 0xFF) == 0xD9))){ return false; } // Skip Segment if (Stream.read(WORD, 0, 2)< 1) return false; Stream.skip(GetWord(WORD[0],WORD[1])- 2); } }catch(Exception e){ e.printStackTrace(); return false; }finally{ if (Stream!=null) Stream.close(); } } // ******************************** // クロスリファレンステーブルの作成 // ******************************** private void Write_CrossReferenceTable(FileOutputStream AStream,int ObjectPosArray[],int Count)throws Exception{ AStream.write("xref\n".getBytes()); AStream.write(String.format("0 %d\n",Count+1).getBytes()); AStream.write("0000000000 65535 f \n".getBytes()); for (int i= 0; i<Count;i++){ AStream.write(String.format("%010d 00000 n \n",ObjectPosArray[i]).getBytes()); } } // ******************************** // コンテンツオブジェクトの作成 // ******************************** private int Write_ContentsObject(FileOutputStream AStream,int ObjectPosArray[],int ObjectIndex,int w,int h)throws Exception{ int Length; int Result = ObjectIndex; /* Contents */ ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write(String.format("%d 0 obj\n",ObjectIndex+1).getBytes()); AStream.write(String.format("<< /Length %d 0 R >>\n",ObjectIndex+2).getBytes()); AStream.write("stream\n".getBytes()); /* stream */ Length = (int)AStream.getChannel().position(); AStream.write("q\n".getBytes()); AStream.write(String.format("%d 0 0 %d 0 0 cm\n",w,h).getBytes()); AStream.write("/Im0 Do\n".getBytes()); AStream.write("Q\n".getBytes()); Length = (int)AStream.getChannel().position() - Length; AStream.write("endstream\n".getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex=ObjectIndex+1; /* stream Length */ ObjectPosArray[ObjectIndex] = (int)AStream.getChannel().position(); AStream.write(String.format("%d 0 obj\n",ObjectIndex+1).getBytes()); AStream.write(String.format("%d\n",Length).getBytes()); AStream.write("endobj\n".getBytes()); ObjectIndex=ObjectIndex+1; Result = ObjectIndex; return Result; } }
確かこのソースコードはAndroidのカメラアプリのコードだったと思います。packageにアプリ名が残ってます :-)
スポンサーリンク
関連記事
公開日:2015年02月18日
記事NO:00238