2015-05-21 2 views
0

Я работаю над простым программным обеспечением для создания изображений для своего университета, и я столкнулся с раздражающей проблемой при получении изображения с камеры. Существует .dll COM библиотека для камеры Apogee Alta U57 (Библиотека и документация здесь: http://www.ccd.com/downloads.html) и есть два возможных способа получения изображения с камеры (при условии, что изображение готово):Получение изображений из регистров камеры

  1. с помощью " ICamera2 camera.image "который возвращает

    " возвращает 2D SAFEARRAY, типа LONG (4 байта на элемента) или INTEGER (2 байта на элемент), который содержит данные изображения. Тип данных (LONG или INTEGER) Возврат контролируется соответствующим свойством ConvertShortToLong. "

  2. с помощью "ICamera2.GetImage (Int pImageBuffer)", который описан как:

    Возвращает указатель на 16 бит без знака, короткие данные, расположенные в памяти . Область данных изображения должна быть назначена приложением до вызова этого метода.

И я довольно хорошо запутаться при использовании второго метода, так как INT! = INT *, , и я действительно не знаю, как передать POINTER TO 16 BIT USHORT. Мой упрощенный метод получения изображения выглядит следующим образом:

 public unsafe uint[] getImage(int width, int height) 
    { 
     // Allocating array of image size (width * height) 
     // where pixel is size of unsigned int (4 BYTES) 
     // possible values: 0 to 4,294,967,295 
     uint[] pixels = new uint[width * height]; 

     // Gets pointer to allocated array and fixes it, 
     // so that it won't be moved by Garbage Collector 
     fixed (uint* ptr = pixels) 
     { 
      camera.GetImage(ptr); 
     } 
     return pixels; 
    } 

Любой человек может объяснить? Я действительно устал (кодировал последние 10 часов), и, может быть, мне что-то не хватает :(

+0

Что случилось с проблемой? Вы можете получить изображение или нет? Вы также должны публиковать фактические подписи этих функций, а не только документацию. – xxbbcc

+0

@xxbbcc Проблема заключается в том, что мой компилятор отклоняет «camera.GetImage (ptr)» Что касается сигнатур функций, то существует только библиотека .dll, содержащая интерфейсы: [DispId (6)] void GetImage (int pImageBuffer); [DispId (7)] –

+0

Что произойдет, если вы откроете DLL с помощью программы просмотра библиотеки типов? https: // MSDN.microsoft.com/en-us/library/d0kh9f4c.aspx – xxbbcc

ответ

0

Хорошо, похоже, ваша функция GetImage ожидает, что вы выделите память пикселей изображения и передадите указатель на выделенные . память вы также ответственны за высвобождение этой памяти, когда вы сделали с ним

Я думаю, что единственное изменение, которое нужно сделать, это литье указатель на long -. функции GetImage принимает long, не указатель (на 32-битных платформах указатель будет 32 бита, на 64-битных платформах - 64 бита).

// Gets pointer to allocated array and fixes it, 
// so that it won't be moved by Garbage Collector 
fixed (uint* ptr = pixels) 
{ 
    long ptrValue = (long) ptr; 

    camera.GetImage(ptrValue); 
} 

Это отличное качество, но это безопасно, так как количество бит подходит для обеих платформ. (Я подозреваю, что вы все равно должны таргетировать либо 32-разрядные, либо 64-разрядные платформы.)

+0

Yay, это работает! В любом случае, GetImage принимает значение int ptr, поэтому я изменил long на int. Компилятор в порядке с этим. Большое спасибо :) –

+0

@Badylu Я рад, что это работает, но что вы имеете в виду «int value ptr»? На какой платформе вы нацеливаетесь? 32-битный или 64-битный? – xxbbcc

+0

Я нацелен на 32-битную платформу, и мой VS2013 уверен, что GetImage принимает значение «int», но не длинное (хотя оно «длинное» в документации) :( –

-1

В документации говорится, что он хочет Uint16. Я, хотя вы должны делать что-то вроде этого

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 


namespace ConsoleApplication1 
{ 
    class Program 
    { 
     [DllImport("Apogee.dll.dll")] 
     extern static int CreateInstance(out IntPtr ICamera2Ptr); 

     [DllImport("Apogee.dll.dll")] 
     extern static void GetImage(ref IntPtr pImageBuffer); 

     static void Main(string[] args) 
     { 
      IntPtr ICamera2Ptr; 
      int results = CreateInstance(out ICamera2Ptr); 

     } 
     static UInt16[] getImage(int width, int height) 
     { 
      // Allocating array of image size (width * height) 
      // where pixel is size of unsigned int (4 BYTES) 
      // possible values: 0 to 4,294,967,295 

      // Allocate memory and calculate a byte count 
      //unsigned short *pBuffer = new unsigned short[ ImgXSize * ImgYSize ]; 
      //unsigned long ImgSizeBytes = ImgXSize * ImgYSize * 2; 

      UInt16[] pixels = new UInt16[width * height]; 
      IntPtr unmanaged_pPixels = Marshal.AllocHGlobal(Marshal.SizeOf(pixels)); 

      //// External operations ApogeeCamera->ExternalShutter = true; 
      //ApogeeCamera->ExternalIoReadout = false; 
      //ApogeeCamera->IoPortAssignment = 0x08; 
      // Even though the exposure time will not be used, still call Expose 
      //ApogeeCamera->Expose(0.001, true); 
      // Check camera status to make sure image data is ready 
      //while (ApogeeCamera->ImagingStatus != Apn_Status_ImageReady); 
      // Get the image data from the camera ApogeeCamera->GetImage((long)pBuffer); 


      GetImage(ref unmanaged_pPixels); 
      pixels = (UInt16[])Marshal.PtrToStructure(unmanaged_pPixels, typeof(UInt16[])); 
      return pixels; 


     } 
    } 
} 
​ 
Смежные вопросы