C#と24bit color TIFFの表示

Windows

C#とLibTiff.Netを使って24bitカラーsingle TIFFを読み込んで表示します。
GUIプログラムなので、今回はWindowsのVisual C#で作成、コンパイルしています。
Linuxでも動作します。

環境など

今回はGUIプログラムなので、Linuxで動かす場合はWindowsで使用した「.NET Framework」のバージョンに対応したパッケージをインストールする必要がある。
今回は、「.Net Framework ver.4.0」を使ったので「libmono-system-windows-forms4.0-cil」をインストールする。
「C#とlibtiff.netの環境構築」の記事を参照。

表示可能な画像

RGB 24bitカラー。
データの並びは「RGB,RGB・・・」。
「BitMiracle.LibTiff.NET.dll」で対応しているので、圧縮(JPEG、ZIP、LZW)・無圧縮どちらでも良い。

Linuxでの実行

Windowsでコンパイルしてから、Sambaや共有ツールなどでコピーする。

chmod 755 ./hoge.exe
./hoge.exe

DLLを登録する

TIFFの解析に「BitMiracle.LibTiff.NET.dll」を使うので「MS Visual C#」に登録する。
「プロジェクト」→「参照の追加」→「参照」タブからファイルを指定する。

出力ウィンドウの表示

「MS Visual C#」を使う場合、「Debug.WriteLine」などでデバッグ情報を出力する。
デバッグ情報は、標準では表示されないので、デバッグ中にメニューバーから操作して表示する。
「デバッグ」→「ウィンドウ」→「出力」

ソース

「MS Visual C#」のソース。
Formの作成と同時に表示する。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
// PixelFormat
using System.Drawing.Imaging;
 
// Marshal.Copy
using System.Runtime.InteropServices;
 
// libtiff.net
using BitMiracle.LibTiff.Classic;
 
// Debug
using System.Diagnostics;
 
namespace Tiff24bitShowForm
{
    public partial class Form1 : Form
    {
        // TIFFの縦横サイズ
        static public int tif_width;
        static public int tif_height;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // RGB 3色
            int colornum = 3;

            // 並び順は「RGB, RGB・・・」。
            // 無圧縮
            string fileName = "24bit.tif";

            byte[] tif_byte = readTiff(fileName, colornum);

            PixelFormat bmpPixelFormat = PixelFormat.Format24bppRgb;
            Bitmap bmp = new Bitmap(tif_width, tif_height, bmpPixelFormat);

            // Pixelデータの領域を確保
          //Rectangle rect = new Rectangle(0, 0, tif_width, tif_height);
            Rectangle rect = new Rectangle(Point.Empty, bmp.Size);

            // BitmapDataのインスタンスを生成・BitmapのLock
            // WriteOnly / ReadWrite / ReadOnly / UserInputBuffer
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmpPixelFormat);
/* 方法1
            // 方法1
            for (i = 0; i < tif_height; i++)
            {
                IntPtr line = (IntPtr)((Int64)bmpData.Scan0 + i * bmpData.Stride);
                Marshal.Copy(tif_byte, i * tif_width, line, tif_height);
            }
*/
///*           
            // 方法2
            // 各項目を抽出
            IntPtr ptr = bmpData.Scan0;

            // マネージ配列からアンマネージメモリ、又はその逆のコピー。
            // アンマネージメモリとは、CLR(Common Language Runtime)に
            // 準拠していないコードを含んでいるコードの総称。
            Marshal.Copy(tif_byte, 0, ptr, tif_byte.Length);
//*/
            // BitmapのLock解除
            bmp.UnlockBits(bmpData);

            // PictureBoxのサイズ設定・描画
            pictureBox1.Image    = bmp;
            pictureBox1.Location = new Point(0, 0);
            pictureBox1.Size     = bmp.Size;

            // Formのサイズ設定・リサイズ禁止
            //this.ClientSize = new System.Drawing.Size(tif_width, tif_height);
            this.ClientSize = bmp.Size;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
        }

        // read TIFF
        private static byte[] readTiff(string fname, int cnum)
        {
            int    i, j;
            ushort samplesperpixel, bitspersample;
            double resolution_x, resolution_y;

            using (Tiff tif = Tiff.Open(fname, "r"))
            {
                if (tif == null)
                {
                    Debug.WriteLine("Can not read Tiff file.");
                }

                tif_width  = tif.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
                tif_height = tif.GetField(TiffTag.IMAGELENGTH)[0].ToInt();

                resolution_x    = tif.GetField(TiffTag.XRESOLUTION)[0].ToDouble();
                resolution_y    = tif.GetField(TiffTag.YRESOLUTION)[0].ToDouble();
                bitspersample   = tif.GetField(TiffTag.BITSPERSAMPLE)[0].ToUShort();
                samplesperpixel = tif.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToUShort();

                // デバッグ出力
                Debug.WriteLine( tif_width );
                Debug.WriteLine( tif_height );
                Debug.WriteLine( resolution_x );
                Debug.WriteLine( resolution_y );
                Debug.WriteLine( bitspersample );
                Debug.WriteLine( samplesperpixel );

                // 画像データの確保
                byte[] buf_byte = new byte[tif_width * tif_height * sizeof(byte) * cnum];

                // 1ラインのデータ配列
                byte[] scanline = new byte[tif.ScanlineSize()];

                //Debug.Indent();

                // 読み取ったデータを格納
                for (i = 0; i < tif_height; i++)
                {
                    tif.ReadScanline(scanline, i);
                    for (j = 0; j < tif_width; j++)
                    {
                        buf_byte[3 * tif_width * i + j * 3 + 0] = scanline[j * 3 + 2];
                        buf_byte[3 * tif_width * i + j * 3 + 1] = scanline[j * 3 + 1];
                        buf_byte[3 * tif_width * i + j * 3 + 2] = scanline[j * 3 + 0];
                      //Debug.WriteLine(scanline[j]);
                    }
                }

                return buf_byte;
            }
        }
    }
}



created by Rinker
¥3,630 (2024/07/02 05:22:54時点 楽天市場調べ-詳細)

Comments