ホーム > カテゴリ > フォーマット変換 >

複数の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