Kann System::Runtime::InteropServices::Marshal::Copy nicht anwenden



  • Hallo,

    ich versuche ein Bild von einer Kamera mit externer lib in was gemanagetes zu kopieren. http://msdn.microsoft.com/de-de/library/5ey6h79d(VS.80).aspx habe ich gelesen und versucht sinngemäß anzuwenden.

    Das Bild ist erstmal in einem Speicherbereich welcher folgendermaßen Deklariert ist:
    char* m_pcImageMemory;

    Folgende Methode funktioniert erwartungsgemäß lahmarschig, zeigt aber immerhin das ich die Kamera ansprechen kann

    ...
    int a,b,c;
    		for (int y=0 ; y < this->m_nSizeY ; y++) {
    			for (int x=0 ; x< this->m_nSizeX ; x++) {
    
    				a=(int)(unsigned char)*(m_pcImageMemory + (4*( (y*m_nSizeX) + x ))  );
    				b=(int)(unsigned char)*(m_pcImageMemory + (4*( (y*m_nSizeX) + x ))+1  );
    				c=(int)(unsigned char)*(m_pcImageMemory + (4*( (y*m_nSizeX) + x ))+2  );
    
    				gdibild->SetPixel(x,y,System::Drawing::Color::FromArgb(a,b,c)); 
    			}
    		}
    

    Ich habe nun versucht das ganze mit System::Runtime::InteropServices::Marshal::Copy etwas fixer zu machen

    resx=1280;
    	resy=1024;
    
    	rect=System::Drawing::Rectangle(0,0,resx,resy); 
    	gdiBild = gcnew System::Drawing::Bitmap
    		(resx,resy,System::Drawing::Imaging::PixelFormat::Format32bppRgb);
    
    	dataArray = gcnew array <unsigned char,1> (resx*resy*4);
    
    ....
    
    		// lock setzen
    		bmpDaten=gdiBild->LockBits
    		(rect,
    		System::Drawing::Imaging::ImageLockMode::ReadWrite,
    		System::Drawing::Imaging::PixelFormat::Format32bppRgb);
    
    		//pointer machen
    		bmpDatenPtr = bmpDaten->Scan0;
    
    		//kopiere ungemanagte Daten ins bmp
    		System::Runtime::InteropServices::Marshal::Copy(m_pcImageMemory,bmpDatenPtr,0,resx*resy*4);
    
    		gdiBild->UnlockBits(bmpDaten);
    

    Die Marshal::Copy zeile läßt sich nicht kompilieren.

    Kompilieren...
    kamera.cpp
    .\kamera.cpp(131) : error C2665: "System::Runtime::InteropServices::Marshal::Copy": Durch keine der 16 Überladungen konnten alle Argumenttypen konvertiert werden.
    c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll: kann
    ....14 weitere ....
    oder "void System::Runtime::InteropServices::Marshal::Copy(System::IntPtr,cli::array<Type,dimension> ^,int,int)"
    with
    [
    Type=unsigned char,
    dimension=1
    ]
    c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll: oder "void System::Runtime::InteropServices::Marshal::Copy(System::IntPtr,cli::array<Type,dimension> ^,int,int)"
    with
    [
    Type=System::IntPtr,
    dimension=1
    ]
    bei Anpassung der Argumentliste '(char *, System::IntPtr, int, int)'

    bmpDatenPtr durch dataArray zu ersetzten führt zum gleichen Fehler.

    Gruß
    predator



  • So, ich habe jetzt mit einer Nacht drüber schlafen rausgefunden, dass noch ein imgMem = IntPtr(m_pcImageMemory) fehlte damit aus einem pointer, der einfach global als char* m_pcImageMemory deklariert ist, ein System::IntPtr wird.

    Das Problem ist jetzt immernoch, dass bei Marshal::Copy entweder Quelle oder Ziel ein cli::array ist. Ich habe aber jetzt aber zwei System::IntPtr. Einer zeigt dahin, wo der Kameratreiber das Bild kopiert und der andere zeigt dahin, wo ich das System::Drawing::Bitmap nach dem LockBits seinen Bildinhalt herbezieht.

    Ich kopiere das ganze jetzt erst vom "Kameraspeicher" in ein cli::array und dann wieder in den "Anzeigespeicher" meines System::Drawing::Bitmap.

    // lock setzen
    		bmpDaten=gdiBild->LockBits
    		(rect,
    		System::Drawing::Imaging::ImageLockMode::ReadWrite,
    		System::Drawing::Imaging::PixelFormat::Format32bppRgb);
    
    		//pointer machen
    		bmpDatenPtr = bmpDaten->Scan0;
    		imgMem = IntPtr(m_pcImageMemory);
    		//kopiere ungemanagte Daten ins bmp
    		System::Runtime::InteropServices::Marshal::Copy(imgMem,dataArray,0,resx*resy*4);
    		System::Runtime::InteropServices::Marshal::Copy(dataArray,0,bmpDatenPtr,resx*resy*4);
    
    		gdiBild->UnlockBits(bmpDaten);
    

    Das geht zwar jetzt in brauchbarer Geschiwndigkeit, scheint mir aber nicht die optimale Lösung zu sein.

    Es müsste doch irgendwie möglich sein die Bilddaten, die von der Kamera kommen und im Speicher liegen, in einem Zug in das System::Drawing::Bitmap zu kopieren.

    Gruß
    predator


Log in to reply