LoginSignup
5
10

More than 1 year has passed since last update.

C# JpgからPDFへ変換(1Jpgファイルを1ページとしたPDFファイルの作成)

Last updated at Posted at 2018-05-30

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

〓ソース

Jpg2Pdf.cs

//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

5
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
10