shadowano Skrevet 19. august 2007 Del Skrevet 19. august 2007 Hei Jeg har en frame av klassen BitMap. Denne framen skal sendes til en funksjon som tar i mot unsigned char* rgb24Buffer, hvor rgb24Buffer er definert som: "The format of rgb24Buffer is RGB24, here the buffer length must >= (width*24+31)/32*4*height" Jeg skjønner ikke helt hvordan jeg skal få trykket BitMap framen inn i funkjonen (uten feilmelding så klart:P) mvh Martin Lenke til kommentar
GeirGrusom Skrevet 19. august 2007 Del Skrevet 19. august 2007 Du forteller ikke helt hva du skal her, men uansett; Jeg regner med at dette er en C funksjon som du importerer med DllImport funksjonen. Bytt om fra RGB24 i spesifikasjonen, til IntPtr, deretter kaller du Bitmap.Lock, og låser hele bildet, med Read & write. Denne funksjonen gir tilbake en Bitmapdata struktur, som du må beholde, helt til du kaller Bitmap.Unlock Bitmapdata.Scan0 inneholder pekeren til bildedata, så lenge dette bildet er 24bit rgb, så vil dette være en array av RBG24. Lenke til kommentar
shadowano Skrevet 19. august 2007 Forfatter Del Skrevet 19. august 2007 (endret) funksjonen jeg sender bildet til er i en importert dll fil ja. Når skal jeg kalle Bitmap.Unlock? Her er koden jeg har til nå: Bitmap frame = camera.LastFrame; BitmapData bmpdata = frame.LockBits(Rectangle.FromLTRB(0, 0, frame.Width, frame.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); camsdk.PlayBuffer(bmpdata.Scan0, frame.Width, frame.Height); Jeg får da følgende feil: Argument '1': cannot convert from 'System.IntPtr' to 'ref byte' (som da peker på PlayBuffer kallet) Var det noe jeg misforstod i starten av det du skrev? -Martin Endret 19. august 2007 av martin82 Lenke til kommentar
GeirGrusom Skrevet 19. august 2007 Del Skrevet 19. august 2007 (endret) Litt, der du har skrevet "ref byte" i DllImport funksjonen, bytter du ut med IntPtr. edit: Pass på at du kaller Lock før du tegner bildet til Graphics objekt. Endret 19. august 2007 av GeirGrusom Lenke til kommentar
shadowano Skrevet 20. august 2007 Forfatter Del Skrevet 20. august 2007 ah, jeg har ikke tilgang til kildekoden til dll filen. camsdk.PlayBuffer() er en funksjon i dll filen, så jeg får ikke endret på den... PlayBuffer() forventer å få en ref byte (i følge feilemldingen over). unsigned char* RGB24 som det står at den skal ta i mot. Alternativet mitt er å få convertert variabelen Bitmap frame til en unsigned char* (som jeg regner med er en peker til bildet?) Lenke til kommentar
GeirGrusom Skrevet 20. august 2007 Del Skrevet 20. august 2007 (endret) Det står noe slikt i CS filen der denne funksjonen er definert: [DllImport("Camsdk.dll")] public static void PlayBuffer(ref byte dst); bytt denne til [DllImport("Camsdk.dll")] public static void PlayBuffer(IntPtr dst); edit: Du kan eventuelt også beholde byte * men da må du skru på "allow unsafe code" samt å skrive [DllImport("Camsdk.dll")] public static unsafe void PlayBuffer(byte* dst); Endret 20. august 2007 av GeirGrusom Lenke til kommentar
shadowano Skrevet 20. august 2007 Forfatter Del Skrevet 20. august 2007 DllImport står ingen steder. Dll filen er lagt til som en referanse til prosjektet. Et demo prosjekt har heller ikke DllImport i koden sin. Her er et utdrag fra c++ kode som benytter PlayBuffer funksjonen: LPBYTE buffer = new BYTE[320*240*3]; srand( (unsigned)time( NULL ) ); for (int i=0; i<320*240*3; i++) { buffer[i] = rand()%255; } m_pVCam->PlayBuffer(buffer, 320, 240); Er en løsning da å opprette en tom byte med frame.width*frame.height*3 og putte inn verdiene for pixlene eller noe? Evt hvordan kan dette gjøres på kjappest/lurest mulig måte? Takker for svar og hjelp så langt:) Lenke til kommentar
GeirGrusom Skrevet 20. august 2007 Del Skrevet 20. august 2007 Ah, skjønner. hmmmm dette ser ut som et problem... Du bruker en ActiveX dll hvis jeg ikke tar helt feil... Dette er et interface, der char * har blitt med feiltagelse oversatt til ref byte, som ikke er riktig, det skal være byte * eller IntPtr, siden ref byte er en referanse til ett byte, og ikke en array. Den kunne da i det minste skrevet byte[].... jeg må bare tenke litt på dette, jeg vet ikke hvordan man får gjort om en byte * eller IntPtr til ref byte... Dette kan sikkert endres, men jeg har ikke vært inne på COM+ DLL-er i .NET Lenke til kommentar
shadowano Skrevet 21. august 2007 Forfatter Del Skrevet 21. august 2007 Setter pris på hjelpen:) De som har laget SDK'en henviser bare til å søke på nettet etter konvertering fra Bitmap til RGB24. Og har ikke funnet noe fornuftig som hjelper... Lenke til kommentar
GeirGrusom Skrevet 21. august 2007 Del Skrevet 21. august 2007 Jeg mistenker sterkt at det har noe med ICustomMarshaler å gjøre, men jeg aner ikke hvordan den funker. Lenke til kommentar
Mr Burns Skrevet 23. august 2007 Del Skrevet 23. august 2007 funksjonen jeg sender bildet til er i en importert dll fil ja. Når skal jeg kalle Bitmap.Unlock? Her er koden jeg har til nå: Bitmap frame = camera.LastFrame; BitmapData bmpdata = frame.LockBits(Rectangle.FromLTRB(0, 0, frame.Width, frame.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); camsdk.PlayBuffer(bmpdata.Scan0, frame.Width, frame.Height); Jeg får da følgende feil: Argument '1': cannot convert from 'System.IntPtr' to 'ref byte' (som da peker på PlayBuffer kallet) Var det noe jeg misforstod i starten av det du skrev? -Martin 9317700[/snapback] HER er noe som kan være nyttig på MSDN... Her er en funksjon som gjør om Bitmap til et gråskala double 2D-array, som ser ut til å fungere for meg. Det burde være en smal sak for deg å gjøre det om slik at det returnerer en 1D-array... private double[,] image2array(Bitmap bi) { Size s = bi.Size; double[,] arr = new double[s.Width, s.Height]; BitmapData bitmapData1 = bi.LockBits(new Rectangle(0, 0, bi.Width, bi.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); int a = 0; unsafe { byte* imagePointer1 = (byte*)bitmapData1.Scan0; for (int i = 0; i < bitmapData1.Height; i++) { for (int j = 0; j < bitmapData1.Width; j++) { // Convert to greyscale a = (imagePointer1[0] + imagePointer1[1] + imagePointer1[2]) / 3; arr[i, j] = a; //4 bytes per pixel imagePointer1 += 3; }//end for j //4 bytes per pixel imagePointer1 += bitmapData1.Stride - (bitmapData1.Width * 3); }//end for i }//end unsafe bi.UnlockBits(bitmapData1); return arr; } Lenke til kommentar
GeirGrusom Skrevet 24. august 2007 Del Skrevet 24. august 2007 Jojo, men problemet er ikke å hente bildedata, problemet er å prøve å kovertere byte * eller IntPtr til ref byte, så jeg tror han må endre på hvordan .NET interop saken gjør jobben sin. Lenke til kommentar
Mr Burns Skrevet 24. august 2007 Del Skrevet 24. august 2007 Jojo, men problemet er ikke å hente bildedata, problemet er å prøve å kovertere byte * eller IntPtr til ref byte, så jeg tror han må endre på hvordan .NET interop saken gjør jobben sin. 9348947[/snapback] ok, hm tenkte at jeg skulle svare på post #9... Men uansett, dette virker vel garantert ikke... byte[] b = new byte[27]; byte bptr = 0; IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(b, 0); bptr = (byte)ptr; cam.PlayBuffer(ref bptr, 3, 3); Lenke til kommentar
GeirGrusom Skrevet 25. august 2007 Del Skrevet 25. august 2007 (endret) nei, fordi da lagrer den adressen i en byte, mens en IntPtr er enten 32-bit eller 64-bit, avhengig av prosessoren. edit: litt bedre forklaring Ref gir referansen til bytet, som inneholder en byte av pekeren til variabelen oversatt til C-ish byte * ptr = BitmapData.Scan0.ToPointer(); // address vil nå inneholde den første byten av pekeren byte address = (byte)ptr; // Gi adressen til et byte som inneholder et byte av pekeren cam.PlayBuffer(&address,...) Tror man må gi en custom marshaler, og skrive et eget interface, men jeg har ikke lest noe om det. edit2: kommet litt lenger, ser ut til at du må bruke verktøyet Tlbimp.exe som ligger i [Visual Studio]\SDK\v2.0\Bin\tlbimp.exe. Det kan hende du må skru på /unsafe og bruke pekere, men det er ikke noe stress. Endret 25. august 2007 av GeirGrusom Lenke til kommentar
shadowano Skrevet 3. september 2007 Forfatter Del Skrevet 3. september 2007 Takker for hjelp. HAr ikke testet noe videre enda, kom fra ferie i går. Men måtte le litt når jeg leste dette fra de som har laget sdk'en: http://www.e2esoft.cn/forum/forum_posts.as...1&get=last#1582 (siste post) Lenke til kommentar
GeirGrusom Skrevet 3. september 2007 Del Skrevet 3. september 2007 Hehe Kanskje de burde lese dette forumet? hehe jeg tror vi er nærme løsningen. Lenke til kommentar
shadowano Skrevet 8. september 2007 Forfatter Del Skrevet 8. september 2007 Greit, da har de laget en ny funksjon som er definert slik: HRESULT PlayBufferEx(in] VARIANT rgb24Buffer, in] unsigned long width, in] unsigned long height); Just like PlayBuffer, but support automation, you should use this in C#/VB/Delphi instead of PlayBuffer, rgb24Buffer is a BYTE array, whose size must >= (width*24+31)/32*4*height. Her er et eksempel i C#: private void btnPlayBuffer_Click(object sender, System.EventArgs e) { btnStop_Click(sender, e); byte[] buffer = new byte [320*240*3]; Random rdm = new Random(); for (int i=0; i<320*240*3; i++) { buffer[i] = (byte)rdm.Next(255); } vcam.PlayBufferEx(buffer, 320, 240); } Jeg er ingen reser i C# (enda), men regner med at det ikke er så vanskelig å få slengt en Bitmap om til en 1 dim variabel og ikke 3 dim som den er nå (hvis jeg har forstått det riktig nå da) ? -Martin Lenke til kommentar
Mr Burns Skrevet 9. september 2007 Del Skrevet 9. september 2007 Kanskje du kan ta utgangspunkt i post #11? Lenke til kommentar
shadowano Skrevet 14. november 2007 Forfatter Del Skrevet 14. november 2007 Da er jeg tilbake etter en liten pause fra prosjektet Jeg tok utgangspunkt i post 11 men da får jeg denne feilmeldingen: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. (AccessViolationException) Det skjer på denne linjen: camsdk.PlayBufferEx(arr, (uint)s.Width, (uint)s.Height); Endringene jeg gjorde i koden fra post 11 er å gjøre arr om til en-dim byte[høyde*bredde] og caste om a til byte. Arr variabelen inneholder alle pixlene i en en-dim array og burde være ok slik jeg ser det. tips til hva det kan være? Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå