2012-03-06 21 views
1

WPFプログラムのデータ値から16ビットのグレースケールイメージを作成したいとします。現在私は、PixelFormats.Gray16が設定されたWriteableBitmapを使用しています。WPFで16ビット+グレースケールイメージを作成する

しかし、私はこれを動作させることができませんし、Microsoftのページ(http://msdn.microsoft.com/en-us/magazine/cc534995.aspx)は、WriteableBitmap経由で書き込み不可能なGray16形式をリストしています。このように他の方法を作る方法を示唆していません。

現在、私のコードはiは、画像の高さとj幅を表し、次のようになりますループ内で動作します。

short dataValue = GetDataSamplePixelValue(myDataValue); 

//the pixel to fill with this data value: 
int pixelOffset = ((i * imageWidth) + j) * bytesPerPixel; 

//set the pixel colour values: 
pixels[pixelOffset] = dataValue; 

私はこれで画像を得るのですが、それはのちょうど束であります縦の黒と白の線。上記の例ではshortbyteに変更されていますが、8ビットのグレースケールデータだけを使用しても問題はありません。

WPFを使用して16ビット/ピクセル以上のグレースケールイメージを作成する方法を知っている人はいますか?この画像も最終的に保存する必要があります。

アドバイスをいただければ幸いです。これにさらに

EDIT

私はいくつかの編集を行っているし、今Gray16 PixelFormatプロパティを使用して賢明な画像を取得しています。イメージプログラムのカラーカウントが256になるので、実際には16ビットであるかどうかを知ることは非常に困難です。イメージがWPFによって制約されているか、イメージプログラムによって制約されているかどうかわかりません明らかに多くの画像プログラムが下位8ビットを無視するので、それをサポートしていません。今のところ、私は自分のものにこだわります。

情報のコードは次のようである:

myBitmap = new WriteableBitmap((int)visualRect.Width, (int)visualRect.Height, 96, 96, PixelFormats.Gray16, null); 

int bytesPerPixel = myBitmap.Format.BitsPerPixel/8; 
ushort[] pixels = new ushort[(int)myBitmap.PixelWidth * (int)myBitmap.PixelHeight]; 

//if there is a shift factor, set the background colour to white: 
if (shiftFactor > 0) 
{ 
    for (int i = 0; i < pixels.Length; i++) 
    { 
     pixels[i] = 255; 
    } 
} 

//the area to be drawn to: 
Int32Rect drawRegionRect = new Int32Rect(0, 0, (int)myBitmap.PixelWidth, (int)myBitmap.PixelHeight); 

//the number of samples available at this line (reduced by one so that the picked sample can't lie beyond the array): 
double availableSamples = myDataFile.DataSamples.Length - 1; 

for (int i = 0; i < numDataLinesOnDisplay; i++) 
{ 
    //the current line to use: 
    int currentLine = ((numDataLinesOnDisplay - 1) - i) + startLine < 0 ? 0 : ((numDataLinesOnDisplay- 1) - i) + startLine; 

    for (int j = 0; j < myBitmap.PixelWidth; j++) 
    {        
     //data sample to use: 
     int sampleToUse = (int)(Math.Floor((availableSamples/myBitmap.PixelWidth) * j)); 

     //get the data value: 
     ushort dataValue = GetDataSamplePixelValue(sampleToUse); 

     //the pixel to fill with this data value: 
     int pixelOffset = (((i + shiftFactor) * (int)myBitmap.PixelWidth) + j); 

     //set the pixel colour values: 
     pixels[pixelOffset] = dataValue; 
    } 
} 

//copy the byte array into the image: 
int stride = myBitmap.PixelWidth * bytesPerPixel; 
myBitmap.WritePixels(drawRegionRect, pixels, stride, 0); 

ユーザはshiftFactorのみ非ゼロで、見ているこの例でSTARTLINEとshiftFactorが既に設定され、データファイルにその時点から依存します画面よりも小さいデータファイルの場合は、この値を使用して画像を垂直方向にセンタリングします。

+1

WriteableBitmapでPixelFormats.Gray16に問題が発生するというエビデンスはありません。あなたの質問は何ですか?どのように画像を扱ういくつかのコードとあなたが得る無効な結果を説明しようとするとどうですか? –

+1

私は分かりません。 2^16は65536のユニークな色を与え、2^8は256を与えます。 – Greg

+0

イメージを保存し、保存されたイメージをロードし、コードで独自のヒストグラムを生成して、実際に正しい色数を得ているかどうかを確認します。あなたが他のプログラムを信頼できない場合は、自分で作ってください! – djdanlib

答えて

0

通常gray16画像ワークと

次の例を表示し、スクリーンは、16ビットのグレースケール画像を表示することができるとは考えにくいですまた、この形式はWindowsではうまくサポートされていません。たとえば、Windows XPでは、写真ビューアに16ビットのグレースケール画像を表示することはできませんが、Windows 7+では可能です(Vistaについてはわかりませんが、それはありません)。

さらに、.NETのオープンTIFメソッドでは、16ビットのグレースケールイメージが読み込まれません。

16ビットのグレースケール画像を読み込んで保存するソリューションで、TIFの一般的な推奨方法はLibTIFFです。次に、TIF全体をロードするか、行ごとに読み込むかを選択できます。最近は、一部のTIFが非常に大きくなり、単一の配列で保持することができないため、1行ずつ読み込むことをお勧めします。

最終的には、画面上に16ビットのグレースケールを表示する心配はありません。システム/モニタの機能によって制限されることがあります。人間の目では、これと8ビットの違いは分かりません。ただし、16ビットをロードまたは保存する必要がある場合は、LibTIFFを使用してください。

2

検索コードのバグまたはあなたの完全なコード参考

var width = 300; 
    var height = 300; 

    var bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray16, null); 
    var pixels = new ushort[width * height]; 
    for (var y = 0; y < height; ++y) 
    for (var x = 0; x < width; ++x) 
    { 
     var v = (0x10000*2 * x/width + 0x10000 * 3 * y/height); 
     var isMirror = (v/0x10000) % 2 == 1; 
     v = v % 0xFFFF; 
     if (isMirror) 
     v = 0xFFFF - v; 

     pixels[y * width + x] = (ushort)v; 
    } 

    bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, width *2, 0); 

    var encoder = new PngBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(bitmap)); 
    using (var stream = System.IO.File.Create("gray16.png")) 
    encoder.Save(stream); 
関連する問題