番外編 DICOM画像とNAS その2


どうしても、患者名が文字化けする

 1.文字化けは避けられないのか

    K-PACSにても、やはり、文字化けします。



    これは、耐えられません。

    K-PACS等の設定ファイルをいじれば、修正できるものでは、ありませんでした....

    仕方が無いので、自分で、何とか、DICOM画像を、文字化け無しに表示する事を考えました。

2.準備

    私の考えるシステムは、NAS(Network Attacehd Storage)を、利用しています。

    NASに、SQLite3 データベースのファイルを、置いています。

    従って

       1. server client system は、不要。 (DICOM Toolkitは、要らない。)

       2.  SQLIte3を使って、C#でプログラムを作るために、薄いラッパークラスを作成する。

       3.  DICOM画像を表示するためには、VTK(The Visualization Toolkit)の、力を借りる。


3.C++を使って、薄いラッパークラスを作成するには

    これが、難しい。

    私には、解らない事ばかりですが、

    すばらしい、お手本のサイトを見つけました。

      SQLiteで”おこづかいちょう”

    私のプログラムは、ここのお手本の、ほとんど、丸写しです、御礼。

    ここで、実験して解った事は、

       unicode で SQLite3 データベースを読むと、文字化けする。

       wchar_t* ではなくて、char*で、データベースを読むと、文字化けしない。

   これを、試したプログラムは

#include "sqlite3.h"
#include <assert.h>
#include <iostream>

using namespace System;
using namespace System::Runtime::InteropServices;

  //System::String ->wchar_t*
  wchar_t* str_to_wchar_t(String^ s)
  { return  (wchar_t*)(Marshal::StringToHGlobalUni(s).ToPointer());}
  //free wchar_t*, etc
  void free_wchar_t(void* p)
  { Marshal::FreeHGlobal(IntPtr((void*)p));}

  //wchar_t* -> System::String
  String^ wchar_t_to_clistr(const void* p)
  { return gcnew String(static_cast<const wchar_t*>(p));}

  //const char* -> Sytem::String
  String^ const_char_to_clistr(const void* p)
  { return Marshal::PtrToStringAnsi(static_cast<IntPtr>((char*)p));}
  
  //char* ->System::String
  String^ char_to_clistr(void* p)
  { return gcnew String((char*)p);}
 
struct sqlite3{};

int main(array<System::String ^> ^args)
{
//  vtkSphereSource^ sphere=gcnew vtkSphereSource();
//  sphere->SetThetaResolution(8);

 sqlite3* db;
 sqlite3_stmt* statement;

 // unicode
 const wchar_t* command = L"select * from DICOMPatients";
 // func16 ==> unicode
 int result=sqlite3_open16(L"L:\\dbase\\conquest.db3",&db);
 if(result !=SQLITE_OK){
  sqlite3_close(db); 
  return 1;
 }
 result=sqlite3_prepare16_v2(db,command,-1,&statement,0);
 assert(result == SQLITE_OK);
 
 while (sqlite3_step(statement) == SQLITE_ROW ) {
  //char*で受ける
  // String^ str1=const_char_to_clistr(sqlite3_column_text(statement,0));
  // String^ str2 =const_char_to_clistr(sqlite3_column_text(statement,1));
  //wchar_t*で受ける
  String^ str1=wchar_t_to_clistr(sqlite3_column_text16(statement,0));
  String^ str2 =wchar_t_to_clistr(sqlite3_column_text16(statement,1));
  
  Console::WriteLine("String^ = {0} ",str1);
  Console::WriteLine("  String^ = {0} \n",str2);
  //char* to String class
 // String^ str=Marshal::PtrToStringAnsi(static_cast<IntPtr>((char*)rep2)) ;
 // Console::WriteLine("\n {0}\n",str);
 }

 //CAPI3REF: Destroy A Prepared Statement Object
 sqlite3_finalize(statement);
 
 //CAPI3REF: Closing A Database Connection
    //The sqlite3_close() routine is the destructor for the [sqlite3] object.
 //Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
 //successfully destroyed and all associated resources are deallocated.
 sqlite3_close(db);
 
 getchar();
 return 0;
}

   wchar_t*で受ける -> 文字化けする


    char*で受ける -> 日本語が、正しく表示される。


    char*で受けた SQLite3データベースの文字列は、 C#の System.Stringに変換済みですから

    VTKで得られたDICOM画像の上に、このSystem.String文字列を表示すれば、よい、と、言う事になります。

    windowベースの、C#プログラムのListViewに表示すれば


    うれしいぞう.....
  
    このC#プログラムは

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using mySQLiteModel;

namespace use_mySQLiteModel_cs
{

    public partial class Form1 : Form
    {
        private mySQLite db;

        private void OnRecordEnumeration(object sender, EventArgs e)
        {
            if (e is EnumStart)
            {
                listView1.BeginUpdate();
            }
            else
                if (e is EnumEnd)
                {
                    listView1.EndUpdate();
                }
                else
                {
                    Record rec = e as Record;
                    ListViewItem item = new ListViewItem();
                    item.Text = rec.ID.ToString();
                    item.Tag = rec.ID;
                    item.SubItems.Add(rec.name.ToString());
                    listView1.Items.Add(item);
                }
        }
        public Form1()
        {
            InitializeComponent();
            db = new mySQLite();
            db.SetRecordListener(this.OnRecordEnumeration);
            db.EnumRecords();

        }
        private Record prepareRecord()
        {
            Record rec = new Record();
            return rec;
        }

    }
}

    このC#プログラムが参照する、

    C++による、薄いラッパークラスは、 mySQLiteModel と、名付けました。

    不思議に、作った、SQLite3.dll を、プロジェクトに含めないと、buildできませんでした。

     

    とにかく、レントゲン装置、CT等から送られてくるDICOMデータは、

    メーカーさんの仕様なので、変えるわけにも行かず、難儀しましたが

    これで、文字化けは、解消されました。

 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

    次は、

    送られた来た DICOMファイルの何処に、画像情報が入っているか?

    なのですが、

    DICOM規格を読んでも、さっぱり解らず。

    VTKでは、DICOM画像データも、自動で、全て読み込んでくれるかも.....

    だとすれば、うれしいな。

H.23.08.26
.