【Unity】PCで画像印刷をする方法


PC(Widnows, Mac)からデフォルトのプリンター設定を呼び出して印刷する方法です。

検証環境
Unity 2017.3.0f3
Mac Sierra 10.12.6
Windows Windows10, Windows8, Windows7

印刷データの保存

印刷する際にパスの指定が必要なため印刷する画像データをローカルに保存する必要があります。

Texture2Dを画像として保存する方法は以下をご覧ください。

印刷する

Macで印刷する

Macだとiprコマンドで印刷するのが楽です。

using UnityEngine;
using System.Diagnostics;

public class hogehoge
{
    public delegate void PrintCallBack(string message);

    public void Print(string filePath, PrintCallBack callback)
    {
        if (callback == null) return;
        if (filePath == null)
        {
            callback("filePath is null");
            return;
        }

        string cmd = "lpr "+filePath;
        
        var process = new Process();
        process.StartInfo.FileName = "/bin/bash";
        process.StartInfo.Arguments = "-c \" " + cmd + " \"";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();

        string output = process.StandardOutput.ReadToEnd();
        process.WaitForExit();
        process.Close();
        
        callback();
    }
}

filrPathは先ほど保存した画像の絶対パスを指定してください。

Windowsで印刷する

Windowsだとiprコマンドの場合、ネットワークプリンタのIPと名前が必要なため、環境が変化するシチュエーションでは使用できません

dllの追加

System.Drawing.dllを使用します。
以下はdllを使用する上での設定です。

  • Assets以下の階層にPluginsフォルダを作成し、System.Drawing.dllを複製します。
    • dllはだいたいここ「C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll」
  • File > Build Settings > Player Settings の Other SettingsでOptimizationのApi Compatibility Levelを「.NET2.0」に変更。

ソースコードの追加

using UnityEngine;
using System.Drawing;
using System.Drawing.Printing;

public class hogehoge
{
    public delegate void PrintCallBack(string message);
    private string imagePath = null;
    private PrintCallBack printCallback;

    public void Print(string filePath, PrintCallBack callback)
    {
        if (callback == null) return;
        if (filePath == null)
        {
            callback("filePath is null");
            return;
        }

        imagePath = filePath;
        printCallback = callback;

        //PrintDocumentオブジェクトの作成
        PrintDocument pd = new PrintDocument();

        //PrintPageイベントハンドラの追加
        pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);

        //Print
        pd.EndPrint += new PrintEventHandler(pd_PrintEnd);

        //PrintControllerプロパティをStandardPrintController
        pd.PrintController = new StandardPrintController();
        try
        {
            //印刷を開始する
            pd.Print();
        }
        catch (System.Exception ex)
        {
            if (printCallback != null) printCallback(ex.Message);
            printCallback = null;
        }
    }
    
    //プリントが終了した
    private static void pd_PrintEnd(object sender, PrintEventArgs e)
    {
        if (printCallback != null) printCallback(imagePath);
        printCallback = null;
    }

    //プリント画像を指定する
    private static void pd_PrintPage(object sender, PrintPageEventArgs e)
    {
        //印刷画像を読み込む
        System.Drawing.Image printImg = null;
        if (System.IO.File.Exists(imagePath))
        {
            printImg = System.Drawing.Image.FromFile(imagePath);
            if (printImg != null)
            {
                DrawAspectFillImage(e.Graphics, printImg, new RectangleF(0,//e.PageSettings.PrintableArea.Left,
                                                                         0,//e.PageSettings.PrintableArea.Top, 
                                                                         e.PageSettings.PrintableArea.Width,
                                                                         e.PageSettings.PrintableArea.Height), true);
                printImg.Dispose();
            }
        }
        //次のページがないことを通知する
        e.HasMorePages = false;
    }

    //プリント画像を描画する
    public static void DrawAspectFillImage(System.Drawing.Graphics graphics, Image image, RectangleF rectangle, bool isKeepAspectRatio)
    {
        if (graphics == null) throw new System.ArgumentNullException();
        if (rectangle.Width <= 0 || rectangle.Height <= 0) throw new System.ArgumentOutOfRangeException();
        if (image == null) return;

        Debug.Log("("+rectangle.Left+","+rectangle.Top+") - ("+rectangle.Width+","+rectangle.Height+")");
        var l = rectangle.Left;
        var t = rectangle.Top;
        var w = (float)image.Width;
        var h = (float)image.Height;
        if (isKeepAspectRatio)
        {
            var r = h / w;
            w = rectangle.Height / r;
            h = rectangle.Height;
            if (w > rectangle.Width)
            {
                w = rectangle.Width;
                h = rectangle.Width * r;
            }
            l += (rectangle.Width - w) / 2;
            t += (rectangle.Height - h) / 2;
        }
        graphics.DrawImage(image, l, t, w, h);
    }
}

VisualStudioが「using System.Drawing」など参照エラーを起こす場合以下を試してみてください。

  • VisualStudioのソリューションエクスプローラーのプロジェクト名の下にある参照を開く。
  • Boo.LangやSystem.hogehogeなどを右クリックし、オブジェクトブラウザーで表示を押す。
  • オブジェクトブラウザーでSystem.Drawingを選択。
  • オブジェクトブラウザーの上方にある、+ボタン(ソリューションエクスプローラー内の選択されたプロジェクトに参照を追加)を押す。

UnityEditorで動くがexeとして実機では動かない場合は「.NET2.0」の設定を忘れている可能性があります。

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です