複数の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
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









