3

ネイティブ イメージ データ構造を 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
        };

そして、これが私のマーシャリング関数です:

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;
        }

私は単純な単一チャネルのケースで自分の機能をテストしています:

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();

これはうまくいきません。デバッグすると、バッファ配列の内部に正しい値があることがわかりますが、BitmapSource を画像に保存すると、想定どおりに表示されません。

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

BitmapSource の使用法に何か欠けていると思います。何か案は?

ありがとう、ディナ

4

1 に答える 1

1

PngBitmapEncoderの代わりに使用しBmpBitmapEncoderます。BmpBitmapEncoderイメージを変形します。PngBitmapEncoder例では正常に動作します。

また、パフォーマンス上の理由から、次を使用してみてください。

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

それ以外の

BitmapSource.Create(Int32, Int32, Double, Double, PixelFormat, BitmapPalette, 
    Array, Int32)
于 2012-03-06T14:26:09.097 に答える