2012-03-06 8 views
2

BitmapSourceにネイティブイメージデータ構造体をマーシャリングしようとしています。ここでピクセルの配列でBitmapSourceを初期化する

は、ネイティブ構造体です:

struct Bitmap_8Bit 
     { 
     public: 
      unsigned char* data; 
      int stride; 
      int rows; 
      int cols; 
      int nChannels; //either 1 or 3. in case of three the order of the channels is BGR 
     }; 

そして、ここでは私のマーシャリング機能です:

BSII::IP::Bitmap_8Bit native; 
native.cols = 8; 
native.rows = 4; 
native.nChannels = 1; 
native.stride = 8; 
int dataLength = native.stride * native.rows; 
native.data = new unsigned char[dataLength]; 

unsigned char gray = 0; 
for (int i = 0; i < native.rows; ++i) 
{ 
    for (int j = 0; j < native.cols; ++j) 
    { 
     native.data[native.stride*i + j] = gray; 
     gray += 10; 
    } 
} 

System::Windows::Media::Imaging::BitmapSource^ managed = msclr::interop::marshal_as<System::Windows::Media::Imaging::BitmapSource^>(native); 

System::IO::FileStream^ stream = gcnew System::IO::FileStream("c:\\workspace\\temp\\managed.bmp", System::IO::FileMode::Create); 
System::Windows::Media::Imaging::BmpBitmapEncoder^ encoder = gcnew System::Windows::Media::Imaging::BmpBitmapEncoder(); 
System::Windows::Media::Imaging::BitmapFrame^ bitmapFrame = System::Windows::Media::Imaging::BitmapFrame::Create(managed); 
encoder->Frames->Add(bitmapFrame); 
encoder->Save(stream); 
stream->Close(); 

このdoesnの:

template<> 
     inline 
      System::Windows::Media::Imaging::BitmapSource^ marshal_as<System::Windows::Media::Imaging::BitmapSource^, Bitmap_8Bit>(const Bitmap_8Bit& nativeBitmap) 
     { 
      System::Windows::Media::PixelFormat format = System::Windows::Media::PixelFormats::Default; 
      System::Windows::Media::Imaging::BitmapPalette^ palette = nullptr; 
      if (nativeBitmap.nChannels == 1) 
      { 
       format = System::Windows::Media::PixelFormats::Gray8; 
       palette = System::Windows::Media::Imaging::BitmapPalettes::Gray256; 
      } 
      else if (nativeBitmap.nChannels == 3) 
      { 
       format = System::Windows::Media::PixelFormats::Bgr24; 
       palette = System::Windows::Media::Imaging::BitmapPalettes::Halftone256; 
      } 
      else 
      { 
       throw gcnew System::InvalidOperationException("Unsupported number of channels " + nativeBitmap.nChannels); 
      } 

      //copy data 
      int pixelDataLength = nativeBitmap.rows*nativeBitmap.stride; 
      System::IntPtr source = System::IntPtr(nativeBitmap.data); 

      cli::array<unsigned char>^ buffer = gcnew cli::array<unsigned char>(pixelDataLength); 
      System::Runtime::InteropServices::Marshal::Copy(source, buffer, 0, pixelDataLength); 

      System::Windows::Media::Imaging::BitmapSource^ managedBitmap = 
       System::Windows::Media::Imaging::BitmapSource::Create(nativeBitmap.cols, nativeBitmap.rows, 
       96, 96, 
       format, palette, 
       buffer, nativeBitmap.stride); 

      return managedBitmap; 
     } 

私は、単純な単一チャネルの場合には、私の機能をテストしています仕事はありません。私はそれをデバッグするとき、バッファ配列が正しい値を内部に持っていることがわかりますが、BitmapSourceをイメージに保存すると、それは想定されているように見えません。

また、Grey256やHalftone256の代わりにnullptrをパレットに使用しようとしましたが、どちらも機能しませんでした。

私はBitmapSourceの使い方に何か不足していると思います。何か案は?

おかげで、 ディナ

答えて

0

利用PngBitmapEncoderの代わりBmpBitmapEncoderBmpBitmapEncoderは画像を変形します。 PngBitmapEncoderとすると、この例は正常に動作します。

BitmapSource.Create(Int32, Int32, Double, Double, PixelFormat, BitmapPalette, 
    IntPtr, Int32, Int32) 

代わりの

BitmapSource.Create(Int32, Int32, Double, Double, PixelFormat, BitmapPalette, 
    Array, Int32) 
+0

ありがとうを:パフォーマンス上の理由からも

は、使用してみてください!それは確かに動作します! – Dina