C# JpgからPDFへ変換
(1Jpgファイルを1ページとしたPDFファイルの作成)
〓出来ること
・1jpgあたり1ページとなる、PDFを作成(出来上がり複数ページ可)
〓準備
・file_list.txt に 1行1jpgファイル名を記載
※このファイル名は固定。ソースコード中に記載。
・PDF化する画像を用意
〓ポイント
・ウィンドウズ dotNetフレームのみ
・コンパイルはWindowsのコマンドラインから
・PDFはスクラッチ(ゼロ)から内容記述
※PDFファイルを、何もないところから書き出しているので、本ソースのみで、(
(ライブラリ等一切必要なく)書き出している点が、メリット
〓実行準備
file_list.txt
- a.jpg
- b.jpg
- c.jpg
(単にjpg名を、テキストファイル内に1行ごと列挙)
〓実行
Jpg2Pdf_v03.exe xxx
※xxxは出来上がりのPDFファイル名を指定する
〓出来上がり
xxx.pdf
〓ソース
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:winexe Jpg2Pdf_v03.cs
using System.IO;
using System.Text;
using System.Drawing;
using System.Collections.Generic;
using System.Drawing.Imaging;
public class Jpg2Pdf_v03
{
public static void Main(string[] args)
{
string path1;//file name
path1 = @".\temp.jpg";
if(args.Length>0){
path1 = @".\" + args[0];
}else{
System.Environment.Exit(0);
}
//■
List<string> file_list = new List<string>();
using (System.IO.StreamReader file = new System.IO.StreamReader(@".\file_list.txt", System.Text.Encoding.UTF8))
{
string line = "";
while ((line = file.ReadLine()) != null)
{
file_list.Add(line);
}
//■
string path2 = path1 + @".pdf";
/// ★★
using (FileStream fs2 = File.OpenWrite(path2))
{
Bitmap image1;
FileInfo fi1;
List<long> list = new List<long>();
adTx(fs2, "%PDF-1.3");
byte[] vals = { 0x25, 0xe2, 0xe3, 0xcf, 0xd3, 0x0d, 0x0a };
fs2.Write(vals, 0, vals.Length);
int pg = 0;
int objnm =0;
int obj_rt =0;
////〓Pg
pg = 0;
foreach (var item in file_list){
path1= item;
image1 = new Bitmap(path1, true);
fi1 = new FileInfo(path1);
/// ★
using (FileStream fs1 = File.OpenRead(path1))
{
objnm = (pg * 6) + 2;
obj_rt = objnm;
// index 2
list.Add(fs2.Position);
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "<</Type /XObject");
adTx(fs2, "/Subtype /Image");
adTx(fs2, "/Filter /DCTDecode");
adTx(fs2, "/ColorTransform 0");
adTx(fs2, "/BitsPerComponent 8");
// Format24bppRgb : Format8bppIndexed
if (image1.PixelFormat == PixelFormat.Format24bppRgb){
adTx(fs2, "/ColorSpace /DeviceRGB");
}else{
adTx(fs2, "/ColorSpace /DeviceGray");
}
adTx(fs2, "/Width " + image1.Width.ToString());
adTx(fs2, "/Height " + image1.Height.ToString());
adTx(fs2, "/Length " + fi1.Length.ToString() + ">>");
adTx(fs2, "stream");
byte[] b = new byte[1];
while (fs1.Read(b,0,b.Length) > 0)
{
fs2.Write(b, 0, b.Length);
}
adTx(fs2, "");
adTx(fs2, "endstream");
adTx(fs2, "endobj");
// index 3
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "<</Type /Page");
adTx(fs2, "/Parent 1 0 R");
adTx(fs2, "/MediaBox [0.0 0.0 595.2 841.68]");
adTx(fs2, "/Contents " + (obj_rt+2) + " 0 R");
adTx(fs2, "/Resources " + (obj_rt+4) + " 0 R");
adTx(fs2, "/Annots " + (obj_rt+5) + " 0 R");
adTx(fs2, ">>");
adTx(fs2, "endobj");
// index 4
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "<</Length " + (obj_rt+3) + " 0 R>>");
adTx(fs2, "stream");
adTx(fs2, "q");
adTx(fs2, "1 0 0 1 0 0 cm");
adTx(fs2, "1 0 0 1 0 0 cm");
adTx(fs2, "595.2 0 0 841.68 0 0 cm");
adTx(fs2, "/I0_0 Do");
adTx(fs2, "Q");
adTx(fs2, "endstream");
adTx(fs2, "endobj");
// index 5
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "67");
adTx(fs2, "endobj");
// index 6
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");
adTx(fs2, "/XObject <<");
adTx(fs2, "/I0_0 " + (obj_rt) + " 0 R");
adTx(fs2, ">>");
adTx(fs2, ">>");
adTx(fs2, "endobj");
// index 7
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "[]");
adTx(fs2, "endobj");
} /// ★
pg ++;
}
////〓Pg
// index 8
list.Add(fs2.Position);
objnm ++;
adTx(fs2, objnm.ToString() + " 0 obj");
adTx(fs2, "<</Type /Catalog");
adTx(fs2, "/Pages 1 0 R");
adTx(fs2, ">>");
adTx(fs2, "endobj");
// index 1
list.Add(fs2.Position);
adTx(fs2, "1 0 obj");
adTx(fs2, "<</Type /Pages");
//--------------
string oj ="[";
for(int lp = 0;lp<=(file_list.Count-1);lp++){/// ▲Pg数
oj = oj + ((lp * 6)+3).ToString() + @" 0 R ";
}
oj = oj + "]";
adTx(fs2, "/Kids " + oj);
adTx(fs2, "/Count " + file_list.Count.ToString()); /// ▲Pg数
//--------------
adTx(fs2, ">>");
adTx(fs2, "endobj");
// index xref
list.Add(fs2.Position);
objnm ++;
adTx(fs2, "xref");
adTx(fs2, "0 " + objnm.ToString()); //15
adTx(fs2, "0000000000 00000 f");
string s;
s = "0000000000" + list[(objnm-1)];
s = s.Substring(s.Length - 10, 10);
adTx(fs2, s + " 00000 n");
for (int i = 0; i < (objnm-1); i++)
{
s = "0000000000" + list[i];
s = s.Substring(s.Length - 10, 10);
adTx(fs2, s + " 00000 n");
}
adTx(fs2, "trailer <</Size " + objnm.ToString() + " /Root " + (objnm-1).ToString() + " 0 R>>");
adTx(fs2, "startxref");
adTx(fs2, list[(objnm-1)].ToString());
adTx(fs2, "%%EOF");
} /// ★★
}}
private static void adTx(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
byte[] vals = { 0x0d}; // , 0x0a
fs.Write(vals, 0, vals.Length);
}
}
参考
(C#) PDFを読み込んで、Stream内をすべて別ファイルに書き出す、サンプルソース
https://qiita.com/santarou6/items/5272458b1e9ff2058327
(C#) PDFを読み込んで、埋め込まれた画像をJPGファイルとして書き出す(DCTDecodeのStream内をママ書き出しているだけなのでかなり雑)
https://qiita.com/santarou6/items/5f011e266929558ede34