Objetivo: Abrir a WebCam utilizando JNA e a API nativa do windows avicap.dll[size=18] [/size]
Obs: O resultado abaixo é diretamente o que acabei de fazer, testes. Quando acabar tudo notifico em um pdf com explicações detalhadas sobre cada linha!
[b]Ferramentas que estou utilizando:
- Sistema Operativo Windows 7
- Netbeans 7.0.1. Pode ser baixado aqui: http://netbeans.org/downloads/
- API JNA. Baixe aqui: http://www.4shared.com/file/GmkHyM5v/jna.html
[/b]
obs: Se você for implementar isso meu filho, pelo amor de Deus, leia antes,não deixe a preguiça lhe pegar!. E to referenciando Wikipedia pelo fato disto não ser artigo cientifico.
Introdução
Irei tratar sobre a conexão com uma webcam nativa(Geralmente para notebooks) ou USB com JNA em Linguagem de Programação Java.
O que é API?
Segundo a wikipedia (2012), é a abreviação para Application Programming Interface (Interface de programação para aplicações). Dentro de uma API contém rotinas, para serem utilizadas em algum aplicativo. Ex: .dll, .jar, etc, podemos chama-las também de bibliotecas.
O que é JNA?
Segundo a Wikipedia (2012), é a abreviação para Java Native Access (Acesso Nativo Java). É uma API do java que nos permite abrirmos outras API que não são nativas do Java como por exemplo dlls do windows.
Isto é bem interessante. Há soluções para este problema como JMF, e DirectShow, que nada mais são que APIs. Mas, eu não gosto de coisa fácil, eu irei utilizar a API Nativa do Windows chamada avicap.dll. Esta API esta localizada na pasta c:\windows\system32\avicap.dll.
Como venho dizendo, antes de sair programando é necessário: 1. Estabelecer um objetivo (O que você quer fazer?); 2. Fazer um levantamento Bibliográfico sobre o assunto, geralmente as monografias atestam o que alguém ja testou e funcionou além da documentação dos fabricantes; 3. Planejar o que irá fazer pode ser UML ou algum algoritmo e por fim 3. Comece a programar na linguagem escolhida.
O fato é que sem se basear em alguma coisa você não faz nada!
Então, o sistema politico da microsoft é complicado pois dificilmente você vê alguma documentação sem um preço a pagar, diferente da politica GNU.
Toda o sistema operacional windows xp até atual, possui a API avicap.dll. E então, o que há dentro dela? Sabemos que é uma Interface, então possuem métodos que se comunicam com o sistema operacional. Então precisamos saber que métodos são estes, afinal ninguém é adivinho. É aqui que precisamos da documentação!
Primeiramente quem a desenvolveu? Se esta no Windows, provavelmente a Microsoft… Procurando na maravilhosa internet chego a isto: http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/4df4fc93-a2d5-401b-ab4a- 056e00f47ec7
Muito escasso para o meu caso, não tenho conhecimentos específicos do sistema operacional Windows. Para isso deveria pesquisar sobre o assunto e mesmo assim a documentação seria paga. Pra quem quer investir compensa, porém meu tempo é curto. Então, passamos a auxiliar nosso conhecimento em fóruns e na vasta internet. Por fim cheguei a isto: http://wenku.baidu.com/view/5f2dc8fc04a1b0717fd5ddc1.html . Pode acreditar, fui encontrar alguma implementação com explicação na China! E valeu, passei a entender melhor o tratamento das assinaturas pelo que fato de ser em uma linguagem que entendo a C.
Com isso, consegui mapear a avicap.dll chamando com JNA em programação Java na IDE Netbeans (eu odeio Eclipse). Vamos lá, passo-a-passo:
Obs: O teste foi realizado com uma WebCam USB e na CAM do meu noteboock! Certifique-se de que a USB que você vai plugar no seu computador não tenha drive nenhum!
Para este caso USB, vamos criar um aplicativo que receberá a imagem da cam. Será um pequeno Software Universal, provavelmente irá funcionar para todos os dispositivos de imagem USB que poderão ser plugados em seu computador. Isso eu não testei ainda, mas vou dar uma de profeta. Porque será hein?! rs
- Plug a WebCam USB no seu computador.
- Abra Painel de controles/Gerenciador de Dispositivos
Se você não instalou o Drive, o sinal de dependência marcada por um simbolo de “!” exclamação irá aparecer. Clique com o Direito e deixe pesquisar automaticamente na internet o drive de conexão USB. No meu caso é o EZCam III, é uma merda, mas tudo bem.
-
Abra o netbeans
-
Crie um novo projeto e nomei. O meu é WebCamU
-
Gosto de programar em Camadas. Vamos criar 2 pacotes: webcamu.interfaces e webcamu.view
-
Pacote webcamu.interfaces
Vamos criar as interfaces necessárias para a aplicação. A primeira delas chamo de MapHWND. Esta contém o mapeamento necessário do HENDLE para a janela. Pesquise sobre isto, nada mais é que o identificador da janela no ambiente windows:
A partir daqui, salve o JNA dentro do projeto e importe para o projeto. No pacote Bibliotecas clique com o direito em AdicionarJar/Pasta… e busque a JNA.jar
[code]import com.sun.jna.FromNativeContext;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
import java.util.HashMap;
import java.util.Map;
public interface MapHWND extends StdCallLibrary{
Map UNICODE_OPTIONS = new HashMap() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
};
Map ASCII_OPTIONS = new HashMap() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
}
};
Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS
: UNICODE_OPTIONS;
public static class HANDLE extends PointerType {
@Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o)) {
return INVALID_HANDLE_VALUE;
}
return o;
}
}
public static class HWND extends HANDLE {
}
HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
{
super.setPointer(Pointer.createConstant(-1));
}
@Override
public void setPointer(Pointer p) {
throw new UnsupportedOperationException("Immutable reference");
}
};
}[/code]
A segunda interface chamo de Avicap32. Nela esta o mapeamento, não esta completo, do que há dentro da DLL:
[code]import com.sun.jna.win32.StdCallLibrary;
public interface Avicap32 extends StdCallLibrary, MapHWND{
//Métodos
public int capCreateCaptureWindowA(
String lpszWindowName, //Cria a função da Janela captura
int dwStye, //estilo da janela
int x, //..
int y, //..
int nWidth, //..
int nHeight, //posição janela e tamanhio
int hWndParent, //identificador da janela pai
int nID); //janela ID
public boolean capGetDriverDescription (
int wDriverIndex,
String lpszName,
int cbName,
String lpszVer,
int cbVer);
/*
public int capSetCallbackOnError (int hwnd, int fpProc);
public int capSetCallbackOnStatus(int hwnd, int fpProc);
public int capSetCallbackOnYield (int hwnd, int fpProc);
public int capSetCallbackOnFrame (int hwnd, int fpProc);
public int capSetCallbackOnVideoStream(int hwnd, int fpProc);
public int capSetCallbackOnWaveStream (int hwnd, int fpProc);
public int capSetCallbackOnCapControl (int hwnd, int fpProc);
public int capSetUserData(int hwnd, int lUser);
public int capGetUserData(int hwnd);
public int capDriverConnect(int hwnd, int I);//I é do tipo Word
public int capDriverDisconnect(int hwnd);
public int capDriverGetName(int hwnd, int szName, int wSize);//wSize é fo tipo Word
public int capDriverGetVersion(int hwnd, int szVer, int wSize);//""
public int capDriverGetCaps(int hwnd, int s, int wSize);//""
public int capFileSetCaptureFile(int hwnd, int szName);
public int capFileGetCaptureFile(int hwnd, int szName, int wSize);//""
public int capFileAlloc(int hwnd, int dwSize);
public int capFileSaveAs(int hwnd, int szName);
public int capFileSetInfoChunk(int hwnd, int lpInfoChunk);
public int capFileSaveDIB(int hwnd, int szName);
public int capEditCopy(int hwnd);
public int capSetAudioFormat(int hwnd, int s, int wSize);//""
public int capGetAudioFormat(int hwnd, int s, int wSize);//""
public int capGetAudioFormatSize(int hwnd);
public int capDlgVideoFormat(int hwnd);
public int capDlgVideoSource(int hwnd);
public int capDlgVideoDisplay(int hwnd);
public int capDlgVideoCompression(int hwnd);
public int capGetVideoFormat(int hwnd, int s, int wSize);//""
public int capGetVideoFormatSize(int hwnd);
public int capSetVideoFormat(int hwnd, int s, int wSize);//""
public int capPreview(int hwnd, int f);//""
public int capPreviewRate(int hwnd, int wMS);//""
public int capOverlay(int hwnd, int f);//""
public int capPreviewScale(int hwnd, int f);//""
public int capGetStatus(int hwnd, int s, int wSize);//""
public int capSetScrollPos(int hwnd, int lpP);
public int capGrabFrame(int hwnd);
public int capGrabFrameNoStop(int hwnd);
public int capCaptureSequence(int hwnd);
public int capCaptureSequenceNoFile(int hwnd);
public int capCaptureStop(int hwnd);
public int capCaptureAbort(int hwnd);
public int capCaptureSingleFrameOpen(int hwnd);
public int capCaptureSingleFrameClose(int hwnd);
public int capCaptureSingleFrame(int hwnd);
public int capCaptureGetSetup(int hwnd, int s, int wSize);//""
public int capCaptureSetSetup(int hwnd, int s, int wSize);//""
public int capSetMCIDeviceName(int hwnd, int szName);
public int capGetMCIDeviceName(int hwnd, int szName, int wSize);//""
public int capPaletteOpen(int hwnd, int szName);
public int capPaletteSave(int hwnd, int szName);
public int capPalettePaste(int hwnd);
public int capPaletteAuto(int hwnd, int iFrames, int iColors);//iFrames é Word
public int capPaletteManual(int hwnd, int fGrab, int iColors);//fGrab é word
*/
//********************************* Constantes ********************************
/******************************************************************************/
public static final short WM_USER = 1024;
public static final int WM_CAP_START = WM_USER;
public static int WS_CHILD = 0x40000000;
public static int WS_VISIBLE = 0x10000000;
public static int SWP_NOZORDER = 0x4;
public static int HWND_BOTTOM = 1;
public static int SWP_NOMOVE = 0x2;
// Defines start of the message range
public static final int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START+ 1);
public static final int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START+ 2);
public static final int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START+ 3);
public static final int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START+ 4);
public static final int WM_CAP_SET_CALLBACK_FRAME = (WM_CAP_START+ 5);
public static final int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START+ 6);
public static final int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START+ 7);
public static final int WM_CAP_GET_USER_DATA = (WM_CAP_START+ 8);
public static final int WM_CAP_SET_USER_DATA = (WM_CAP_START+ 9);
public static final int WM_CAP_DRIVER_CONNECT = 0x40a;//(WM_CAP_START+ 10);
public static final int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START+ 11);
public static final int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START+ 12);
public static final int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START+ 13);
public static final int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START+ 14);
public static final int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START+ 20);
public static final int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START+ 21);
public static final int WM_CAP_FILE_ALLOCATE = (WM_CAP_START+ 22);
public static final int WM_CAP_FILE_SAVEAS = (WM_CAP_START+ 23);
public static final int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START+ 24);
public static final int WM_CAP_FILE_SAVEDIB = (WM_CAP_START+ 25);
public static final int WM_CAP_EDIT_COPY = (WM_CAP_START+ 30);
public static final int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START+ 35);
public static final int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START+ 36);
public static final int WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START+ 41);
public static final int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START+ 42);
public static final int WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START+ 43);
public static final int WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START+ 44);
public static final int WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START+ 45);
public static final int WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START+ 46);
public static final int WM_CAP_SET_PREVIEW = 0x432;//(WM_CAP_START+ 50);
public static final int WM_CAP_SET_OVERLAY = (WM_CAP_START+ 51);
public static final int WM_CAP_SET_PREVIEWRATE = 0x434;//(WM_CAP_START+ 52);
public static final int WM_CAP_SET_SCALE = 0x435;//(WM_CAP_START+ 53);
public static final int WM_CAP_GET_STATUS = (WM_CAP_START+ 54);
public static final int WM_CAP_SET_SCROLL = (WM_CAP_START+ 55);
public static final int WM_CAP_GRAB_FRAME = (WM_CAP_START+ 60);
public static final int WM_CAP_GRAB_FRAME_NOSTOP = (WM_CAP_START+ 61);
public static final int WM_CAP_SEQUENCE = (WM_CAP_START+ 62);
public static final int WM_CAP_SEQUENCE_NOFILE = (WM_CAP_START+ 63);
public static final int WM_CAP_SET_SEQUENCE_SETUP = (WM_CAP_START+ 64);
public static final int WM_CAP_GET_SEQUENCE_SETUP = (WM_CAP_START+ 65);
public static final int WM_CAP_SET_MCI_DEVICE = (WM_CAP_START+ 66);
public static final int WM_CAP_GET_MCI_DEVICE = (WM_CAP_START+ 67);
public static final int WM_CAP_STOP = (WM_CAP_START+ 68);
public static final int WM_CAP_ABORT = (WM_CAP_START+ 69);
public static final int WM_CAP_SINGLE_FRAME_OPEN = (WM_CAP_START+ 70);
public static final int WM_CAP_SINGLE_FRAME_CLOSE = (WM_CAP_START+ 71);
public static final int WM_CAP_SINGLE_FRAME = (WM_CAP_START+ 72);
public static final int WM_CAP_PAL_OPEN = (WM_CAP_START+ 80);
public static final int WM_CAP_PAL_SAVE = (WM_CAP_START+ 81);
public static final int WM_CAP_PAL_PASTE = (WM_CAP_START+ 82);
public static final int WM_CAP_PAL_AUTOCREATE = (WM_CAP_START+ 83);
public static final int WM_CAP_PAL_MANUALCREATE = (WM_CAP_START+ 84);
// Following added post VFW 1.1
public static final int WM_CAP_SET_CALLBACK_CAPCONTROL = (WM_CAP_START+ 90);
// Defines end of the message range
public static final int WM_CAP_END = WM_CAP_SET_CALLBACK_CAPCONTROL;
public static final int IDS_CAP_BEGIN = 300; //(* "Capture Start" *)
public static final int IDS_CAP_END = 301; //(* "Capture End" *)
public static final int IDS_CAP_INFO = 401; //(* “%s” )
public static final int IDS_CAP_OUTOFMEM = 402; //( “Out of memory” )
public static final int IDS_CAP_FILEEXISTS = 403; //( “File ‘%s’ exists – overwrite it?” )
public static final int IDS_CAP_ERRORPALOPEN = 404; //( “Error opening palette ‘%s’” )
public static final int IDS_CAP_ERRORPALSAVE = 405; //( “Error saving palette ‘%s’” )
public static final int IDS_CAP_ERRORDIBSAVE = 406; //( “Error saving frame ‘%s’” )
public static final int IDS_CAP_DEFAVIEXT = 407; //( “avi” )
public static final int IDS_CAP_DEFPALEXT = 408; //( “pal” )
public static final int IDS_CAP_CANTOPEN = 409; //( “Cannot open ‘%s’” )
public static final int IDS_CAP_SEQ_MSGSTART = 410; //( “Select OK to start capture\nof video sequence\nto %s.” )
public static final int IDS_CAP_SEQ_MSGSTOP = 411; //( “Hit ESCAPE or click to end capture” *)
public static final int IDS_CAP_VIDEDITERR = 412; //(* “An error occurred while trying to run VidEdit.” )
public static final int IDS_CAP_READONLYFILE = 413; //( “The file ‘%s’ is a read-only file.” )
public static final int IDS_CAP_WRITEERROR = 414; //( “Unable to write to file ‘%s’.\nDisk may be full.” )
public static final int IDS_CAP_NODISKSPACE = 415; //( “There is no space to create a capture file on the specified device.” )
public static final int IDS_CAP_SETFILESIZE = 416; //( “Set File Size” )
public static final int IDS_CAP_SAVEASPERCENT = 417; //( “SaveAs: %2ld%% Hit Escape to abort.” *)
public static final int IDS_CAP_DRIVER_ERROR = 418; //(* Driver specific error message *)
public static final int IDS_CAP_WAVE_OPEN_ERROR = 419; //(* “Error: Cannot open the wave input device.\nCheck sample size, frequency, and channels.” )
public static final int IDS_CAP_WAVE_ALLOC_ERROR = 420; //( “Error: Out of memory for wave buffers.” )
public static final int IDS_CAP_WAVE_PREPARE_ERROR = 421; //( “Error: Cannot prepare wave buffers.” )
public static final int IDS_CAP_WAVE_ADD_ERROR = 422; //( “Error: Cannot add wave buffers.” )
public static final int IDS_CAP_WAVE_SIZE_ERROR = 423; //( “Error: Bad wave size.” *)
public static final int IDS_CAP_VIDEO_OPEN_ERROR = 424; //(* “Error: Cannot open the video input device.” )
public static final int IDS_CAP_VIDEO_ALLOC_ERROR = 425; //( “Error: Out of memory for video buffers.” )
public static final int IDS_CAP_VIDEO_PREPARE_ERROR = 426; //( “Error: Cannot prepare video buffers.” )
public static final int IDS_CAP_VIDEO_ADD_ERROR = 427; //( “Error: Cannot add video buffers.” )
public static final int IDS_CAP_VIDEO_SIZE_ERROR = 428; //( “Error: Bad video size.” *)
public static final int IDS_CAP_FILE_OPEN_ERROR = 429; //(* “Error: Cannot open capture file.” )
public static final int IDS_CAP_FILE_WRITE_ERROR = 430; //( “Error: Cannot write to capture file. Disk may be full.” )
public static final int IDS_CAP_RECORDING_ERROR = 431; //( “Error: Cannot write to capture file. Data rate too high or disk full.” )
public static final int IDS_CAP_RECORDING_ERROR2 = 432; //( “Error while recording” )
public static final int IDS_CAP_AVI_INIT_ERROR = 433; //( “Error: Unable to initialize for capture.” )
public static final int IDS_CAP_NO_FRAME_CAP_ERROR = 434; //( “Warning: No frames captured.\nConfirm that vertical sync interrupts\nare configured and enabled.” )
public static final int IDS_CAP_NO_PALETTE_WARN = 435; //( “Warning: Using default palette.” )
public static final int IDS_CAP_MCI_CONTROL_ERROR = 436; //( “Error: Unable to access MCI device.” )
public static final int IDS_CAP_MCI_CANT_STEP_ERROR = 437; //( “Error: Unable to step MCI device.” )
public static final int IDS_CAP_NO_AUDIO_CAP_ERROR = 438; //( “Error: No audio data captured.\nCheck audio card settings.” )
public static final int IDS_CAP_AVI_DRAWDIB_ERROR = 439; //( “Error: Unable to draw this data format.” )
public static final int IDS_CAP_COMPRESSOR_ERROR = 440; //( “Error: Unable to initialize compressor.” )
public static final int IDS_CAP_AUDIO_DROP_ERROR = 441; //( “Error: Audio data was lost during capture, reduce capture rate.” *)
//(* status string IDs )
public static final int IDS_CAP_STAT_LIVE_MODE = 500; //( “Live window” )
public static final int IDS_CAP_STAT_OVERLAY_MODE = 501; //( “Overlay window” )
public static final int IDS_CAP_STAT_CAP_INIT = 502; //( “Setting up for capture - Please wait” )
public static final int IDS_CAP_STAT_CAP_FINI = 503; //( “Finished capture, now writing frame %ld” )
public static final int IDS_CAP_STAT_PALETTE_BUILD = 504; //( “Building palette map” )
public static final int IDS_CAP_STAT_OPTPAL_BUILD = 505; //( “Computing optimal palette” )
public static final int IDS_CAP_STAT_I_FRAMES = 506; //( “%d frames” )
public static final int IDS_CAP_STAT_L_FRAMES = 507; //( “%ld frames” )
public static final int IDS_CAP_STAT_CAP_L_FRAMES = 508; //( “Captured %ld frames” )
public static final int IDS_CAP_STAT_CAP_AUDIO = 509; //( “Capturing audio” )
public static final int IDS_CAP_STAT_VIDEOCURRENT = 510; //( “Captured %ld frames (%ld dropped) %d.%03d sec.” )
public static final int IDS_CAP_STAT_VIDEOAUDIO = 511; //( “Captured %d.%03d sec. %ld frames (%ld dropped) (%d.%03d fps). %ld audio bytes (%d,%03d sps)” )
public static final int IDS_CAP_STAT_VIDEOONLY = 512; //( “Captured %d.%03d sec. %ld frames (%ld dropped) (%d.%03d fps)” )
public static final int IDS_CAP_STAT_FRAMESDROPPED = 513; //( “Dropped %ld of %ld frames (%d.%02d%%) during capture.” *)
}[/code]
A outra interface é a USER32 que mapeia a dll user32.dll que irei usar para setar as configurações, porque estou usando as constantes da interface e não os métodos:
[code]import com.sun.jna.win32.StdCallLibrary;
public interface User32 extends StdCallLibrary, MapHWND{
public boolean DestroyWindow(int hndw);
public boolean ShowWindow(long hWnd, int nCmdShow);
public HWND FindWindow(String winClass, String title);
public int SetWindowPos(
int hwnd,
int hWndInsertAfter,
int x,
int y,
int cx,
int cy,
int wFlags);
public int SendMessageA(
int hwnd,
int wMsg,
int wParam,
Object lParam);
}
[/code]
As três interfaces estão prontas.
No pacote webcamu.views, adicione um Formulário JFrame, iremos trabalhar com GUI. Adicione um botão e um rótulo da paleta Controles Swing.
Dê dois clique no botão ou se preferir, na paleta propriedade do Botão, clique em eventos e acione ActionPerformed.
Adicione este código:
[code] Frame = new JFrame();
Frame.setLayout(null);
Frame.setSize(320,240);
Frame.setLocation(100, 100);
Frame.setTitle(“WebCam”);
//Frame.setContentPane(getJContentPane());
Frame.setVisible(true);
WComponentPeer cpp = (WComponentPeer) Frame.getPeer();
//cpp.setEnabled(true);
//cpp.setVisible(true);
System.out.println("cpp: "+cpp);
long h = cpp.getHWnd();
int id = (int)h;
int hWnd = 0;
int DeviceID = 0;
la.setText(String.valueOf(id));
System.out.println("id(Frame): "+id);
Avicap32 libA = (Avicap32) Native.loadLibrary("AviCap32", Avicap32.class);
User32 libU = (User32) Native.loadLibrary("User32", User32.class);
String DeviceIndex = String.valueOf(DeviceID);
try{
hWnd = libA.capCreateCaptureWindowA(DeviceIndex, Avicap32.WS_VISIBLE | Avicap32.WS_CHILD, 0, 0, 320, 240, id, 0);
System.out.println("hwnd(capCreateCaptureWinA): "+hWnd);
}catch(Exception ex){JOptionPane.showMessageDialog(null, ex.toString());}
//Connect to device
if (libU.SendMessageA(hWnd, Avicap32.WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0){
//libU.SendMessageA(hWnd, Avicap32.WM_CAP_GET_VIDEOFORMAT, -1, 0);System.out.println("WM_CAP_SEQUENCE_SETUP: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SEQUENCE_SETUP, 0, 0));
libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0);System.out.println("WM_CAP_SET_SCALE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0));
libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0);System.out.println("WM_CAP_SET_OVERLAY: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0));
//libU.SendMessageA(hWnd, Avicap32.WM_CAP_DLG_VIDEOFORMAT, 0, 0);System.out.println("WM_CAP_DLG_VIDEOFORMAT: ");
//ibU.SendMessageA(hWnd, Avicap32.WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);System.out.println("WM_CAP_DLG_VIDEOCOMPRESSION: ");
//libU.SendMessageA(hWnd, Avicap32.IDS_CAP_BEGIN , 0, 0);
//libU.SendMessageA(hWnd, Avicap32.WM_CAP_SEQUENCE , -1, 0);System.out.println("WM_CAP_SEQUENCE: "+libU.SendMessageA(hWnd,Avicap32.WM_CAP_SEQUENCE , 0, 0));
while(true){
libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 66, 0);System.out.println("WM_CAP_SET_PREVIEWRATE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 100, 0));
libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0);System.out.println("WM_CAP_SET_PREVIEW: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0));
//libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, 1, 0);System.out.println("WM_CAP_SET_OVERLAY: "+libU.SendMessageA(hWnd,Avicap32.WM_CAP_SET_OVERLAY, 1, 0));
libU.SendMessageA(hWnd, Avicap32.WM_CAP_GRAB_FRAME, -1, 0);System.out.println("WM_CAP_GRAB_FRAME: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_GRAB_FRAME , -1, 0));
libU.SetWindowPos(hWnd, Avicap32.HWND_BOTTOM, 0, 0, 320, 240, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER);
System.out.println("SetWindowPos: "+libU.SetWindowPos(hWnd, 0, 0, 0, 320, 240, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER));
}
}else{
//Error connecting to device close window
libU.DestroyWindow(hWnd);
JOptionPane.showMessageDialog(null, "Fora do SendMessageA");
}
[/code]
Note o seguinte, a constante WM_CAP_DLG_VIDEOSOURCE, trata do dispositivo USB. Automaticamente, se não identificado a precença nativa da Webcam (como o caso do notebook), será aberto uma janela para especificar o drive existente. Caso prefira podera cliar uma rotina identificando tais configurações como deixei comentado o formato do video e a compressão. Interessante isso.
Acerte as dependências que faltarem e VOILÁ.
- Dê o RUN da aplicação.
- Clique no botão
- No meu caso é a USB, especifiquei o drive que instalei no Gerenciador de Dispositivos e funcionou.
Não utilizei JMF nem DirectShow para isso, foi mapeamento da API Nativa do windows avicap.dll para abrir imagem. Como você pode perceber, com ela tratamos de audio e video.
Além disso, existe a User32 e muitas outras, que com a documentações, você poderá fazer coisas impressionantes com o sistema operativo, neste caso Windows.
Sobre algumas informações adicionais sobre algumas dll poderá encontrar neste site: http://www.andreavb.com digite a API que vc quer, não há muitas (http://www.andreavb.com/API_USER32.html), porém ajudou-me muito. A linguagem existente de mapeamento estão em VB, super facil de entender.
Problema Solucionado!
É isso. Estou agora na Opencv.
Referência
MICROSOFT (Org.). Acessar imagem da WebCam. Disponível em: <http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/4df4fc93-a2d5-401b-ab4a- 056e00f47ec7>. Acesso em: 10 jan. 2010.
WIKIPEDIA (Org.). API. Disponível em: http://pt.wikipedia.org/wiki/API. Acesso em: 29 jan. 2012.
WIKIPEDIA (Org.). JNA. Disponível em: http://en.wikipedia.org/wiki/Java_Native_Access. Acesso em: 29 jan. 2012.