どのように私は、.NET x64の16ビット画像を読み込む/保存することができますか?

StackOverflow https://stackoverflow.com/questions/2294570

質問

の前に、私は、Win32を使用していたとき、私はロードするために、ビットのビットマップのセーブ FreeImage に使用8ビットよりも深さも大きいです。私は医療画像をやっているので、とのすべての画像Iの仕事だし、誰もが何かを言う前に、はい、私と私の顧客は、ダイナミックレンジの11ビットまたは12ビットで高輝度、高コントラストのモニターにたくさんのお金を費やしていること。実際には、あなたが興味があれば、マンモグラフィのincldue Aを実行するためのACRによって要件ダイナミックレンジの少なくとも10ビットで監視。

私は、メモリのオーバーヘッドのためのx64に切り替えて一つのプラットフォーム上に私の開発の全てを取得し、モードをコンパイル。私はむしろ、Win32のにバックアップしないだろう、と私の顧客は(そして実際に変更を強制的に)私と一緒に右にあります。 FreeImageは、64ビットWindows上でコンパイルされません。それは、コンパイラだけで処理できないコードで_asmディレクティブを持っています。

私は、Microsoftのクラスでネイティブの.NETサポートを試してみようと思いました。長い話を短く:彼らは仕事をしませんし、非常に限られたエラーメッセージで失敗します。私は、MicrosoftがまだFormat16bppGrayScaleクラスをサポートしていないからだと疑っています。

たぶん私のコードに問題があります。ここに私のコードは書き込みのためです。

Bitmap theBitmap = new Bitmap(inImage.XSize, inImage.YSize, PixelFormat.Format16bppGrayScale);

//have to go with lockbits
Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData =
    theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
    PixelFormat.Format16bppGrayScale);
IntPtr ptr = bmpData.Scan0;
int theByteSize = theBitmap.Width * theBitmap.Height *2;
byte[] theByteBuffer = new byte[theByteSize];
System.Buffer.BlockCopy(inImage.Data, 0, theByteBuffer, 0, theByteSize);
System.Runtime.InteropServices.Marshal.Copy(theByteBuffer, 0, ptr, theByteSize);
theBitmap.UnlockBits(bmpData);

theBitmap.Save(inDirectory + "\\" + inName);
theBitmap.Dispose();

このコードは、

を使用してプログラムをクラッシュ
An unhandled exception of type 
 'System.Runtime.InteropServices.ExternalException' occurred in 
 System.Drawing.dll

Additional information: A generic error occurred in GDI+.

興味深い、私はこのような画面にこのイメージを描きたいことはありません、特に以来(それは!素敵なのだろうが)が、ちょうどセーブ/ロード機能を使用したいと思います。画像は、(プログラムがクラッシュしても)、ディスクに書き込まれますんし、次の読み取りコードは、プログラムがクラッシュします:

Bitmap theBitmap = new Bitmap(theCompleteName, false);
ushort[] theData = new ushort[theBitmap.Width * theBitmap.Height];
int x, y;

switch (theBitmap.PixelFormat)
{
    case PixelFormat.Format16bppGrayScale:
        //have to go with lockbits
        {           
            Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = 
                theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
                PixelFormat.Format16bppGrayScale);
            IntPtr ptr = bmpData.Scan0;//scanline approach left over from FreeImage

            for (y = 0; y < theBitmap.Height; ++y){
                byte[] scanline = new byte[theBitmap.Width*2];
                System.Runtime.InteropServices.Marshal.Copy(ptr, scanline, y * theBitmap.Width * 2, theBitmap.Width * 2);
                System.Buffer.BlockCopy(scanline, 0, theData, y * theBitmap.Width * 2, theBitmap.Width * 2);
            }
            theBitmap.UnlockBits(bmpData);
        }
        break;
    //for colors, just take the red and call it a day


    case PixelFormat.Format24bppRgb:
    case PixelFormat.Format32bppArgb://really stupid reading code, always works
        for (y = 0; y < theBitmap.Height; ++y) {
            for (x = 0; x < theBitmap.Width; ++x) {
                theData[y * theBitmap.Width + x] = (byte)(theBitmap.GetPixel(x, y).R);
            }
        }
        break;
}
theNewImage = new ImageContainer(theData, theBitmap.Width, theBitmap.Height, inName, inAssessmentID);
theBitmap.Dispose();//not needed, anymore

このコードは、エラーでプログラムがクラッシュします:

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll

Additional information: Parameter is not valid.

これらの結果は、Microsoftがまだピクセルフォーマットの列挙のFormat16bppGrayScale部分を固定していないことを教えてください。それは残念だ。

それでは、私は負荷に使用することができますし、.NET?

とのx64上の16ビットグレースケール画像を保存

(EDIT:DICOMは、UIDとその他の必要なフィールドのセットを必要と私はDICOM画像を保存することができますが、私はアルゴリズムがなどの音であり、ことを確認するために、非患者データの実験を実行する必要があることを追加する必要があります。行き過ぎ私は必要なもののためであること;。現時点では、私だけで必要な画像ではなく、患者のデータは、)

役に立ちましたか?

解決

FreeImage のx64のにコンパイルすることができます。ここでの手順以下のあなたを_asmディレクティブを回避することができます。また、ページの下部にコンパイルされ、64ビットのDLLがあります。

最新バージョン(3.15.1)は、既にこの修正プログラムが含まれています。私は(私は自分のプロジェクトでFreeImageを使用する好奇心旺盛されています)しようとするソース配布を拾ってきたとx64プラットフォームは、すぐに罰金をコンパイルします。

他のヒント

私は間違いでしょう本当にあなたの質問に答えていないよしかし、以前に Neodnyamicするによって販売されてImageDrawコンポーネントを使用していると、それは、再びお勧めします(および使用します)。それは自由が、小さな投資価値は十分ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top