|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
RÉCUPÉRER LES IMAGES D’UNE CAMERA IP TRANSMETTANT UN FLUX MJPEG
Information sur la source
Description
Récupérer les images d’une camera IP ( une DLINK DCS-900) transmettant un flux MJPEG (et non MPEG), transformation en image bitmap puis affichage. Cette base me sert en robotique mobile (simple vision à distance) et pour différents projet (reconnaissance des formes, d’iris etc..) avec traitement. Elle utilise la librairie PLIB ( plib.net plib.org) pour le transfert entre la camera (donc facilement migrable sous linux), par contre elle utilise les fonctions windows pour la décompression JPEG ( mais on doit pouvoir facilement utiliser la librairie JPEG de ijg.org )
Source
- /******************************************************************
- * recuperation d'un flux Mjpeg venant d'une camera IP (DCS-900) *
- * 320x200 *
- * ouvre une connexion tcp client, envoi une requete http, traite *
- * le flux reçu, extrait les images jpeg, les convertit, et *
- * affiche le resultat *
- ******************************************************************
- * Copyright 2006 Grimal sylvain *
- * utilisation libre pour application non commerciale *
- ******************************************************************
- * linker avec: net ul (plib) libsock32 libgdi32 libuser32 *
- * libole32 liboleaut32 libolepro32 libuuid (.a ou .lib selon *
- * compilateur) *
- ******************************************************************/
-
- #include <windows.h>
- #include <olectl.h>
- #include "include/netsocket.h" // librarie PLIB voir plib.net ou plib.org
-
- #define TCP true
- #define UDP false
- #define longMaxJpeg 16384 // longueur maximale d'une image jpeg reçue (suffisant pour du 320x200)
-
- unsigned char image[longMaxJpeg];
-
- HWND hWmain;
- netSocket *sockr;
-
- // DC d'affichage
- HDC hdcSortie;
- // Bitmap après convertion du jpeg
- HBITMAP hbmp;
-
- /*******************************************************
- * convertion d'une image Jpeg en bitmap *
- * utilisation ole de windows cf msdn *
- *******************************************************/
- HBITMAP convertJpegBmp(LPBYTE pmem, DWORD nSize)
- {
- HRESULT hr;
- CoInitialize(0);
- HBITMAP hbmp_dst = 0;
-
- // copie image jpeg dans global
- HGLOBAL hgbl =(HGLOBAL)GlobalAlloc(GMEM_FIXED, nSize);
- memcpy(hgbl, pmem, nSize);
-
- // création du stream d'échange
- IStream* stream = 0;
- // image jpeg dans global dans stream
- hr = CreateStreamOnHGlobal(hgbl, TRUE, &stream);
- if(!SUCCEEDED(hr) || !stream) { // si erreur libération des objets déja crées
- GlobalFree(hgbl);
- CoUninitialize();
- } else {
- // création d'une 'picture'
- IPicture* picture = 0;
- // conversion stream vers picture
- hr = OleLoadPicture(stream, nSize, 0, IID_IPicture, (void**)&picture);
- if(!SUCCEEDED(hr) || !picture) { // si erreur libération des objets déja crées
- stream->Release();
- GlobalFree(hgbl);
- CoUninitialize();
- } else {
- // recuperation du handle de la 'picture'
- HBITMAP hbmp_src;
- picture->get_Handle((OLE_HANDLE *)&hbmp_src);
-
- // recuperation du handle du bitmap de la 'picture'
- BITMAP bmp;
- GetObject(hbmp_src, sizeof bmp, &bmp);
- // bmp est le bitmap resultant mais son pointeur vers le contenu pointe vers le contenu de 'picture'
- // comme on va dechargé la 'picture' on copie dans une autre zone memoire
- hbmp_dst = (HBITMAP)CopyImage(hbmp_src, IMAGE_BITMAP, 0, 0, 0);
-
- picture->Release();
- stream->Release();
- GlobalFree(hgbl);
- CoUninitialize();
- }
- }
- return hbmp_dst;
- }
-
- /****************************************************
- * affiche une image jpeg contenue dans le tableau *
- * image[52 ou 53 à longueur-5] *
- ****************************************************/
- int afficheImage(HWND hwnd, DWORD longueur)
- {
- HDC hdc;
- DWORD debut;
- // recherche debut variable selon texte indication taille image
- debut=50; // normalement debut=52 si taille<10Ko et 53 si >
- while (!((image[debut]==0xFF) & (image[debut+1]==0xD8)) & (debut<54)) {
- debut ++;
- }
- // test entete et fin fichier JPEG
- if ((image[debut]==0xFF) & (image[debut+1]==0xD8) &(image[longueur-6]==0xFF)&(image[longueur-5]==0xD9)) {
- // conversion de l'image JPEG en Bitmap (ole Windows)
- hbmp = convertJpegBmp((LPBYTE) &image[debut], longueur-debut-4);
-
- // et affichage (GDI windows)
- hdc = GetDC(hwnd);
- SelectObject(hdcSortie, hbmp);
- BitBlt(hdc, 0, 0, 320, 240, hdcSortie, 0, 0, SRCCOPY);
- ReleaseDC(hwnd,hdc);
- // et destruction du bitmap
- DeleteObject(hbmp);
- }
- }
-
-
- /***************************************************************
- * Ouverture d'un socket TCP IP Plib port de sortie *
- * geré automatiquement par plib non contrôlable mais avantage *
- * gestion automatique si lancement de plusieurs applications *
- ****************************************************************/
- netSocket* OpenTcpMjpegParser(char* ip,unsigned int port)
- {
- netSocket *sockr;
- netInit();
- sockr= new netSocket();
- sockr->open(TCP);
- sockr->connect(ip,port);
- return sockr;
- }
-
- /***************************************************************
- * Fermeture du socket TCP IP *
- ****************************************************************/
- int CloseTcpMjpegParser(netSocket *sockr)
- {
- sockr->close();
- }
-
- /****************************************************************
- * routine principale: ouvre une connection TCP/IP entre l'hote *
- * (le client) et la camera (le serveur), envoi la demande http *
- * *
- *****************************************************************/
- DWORD WINAPI TcpMjpegParser( void *param)
- {
- char rbuffer[2048];
- char limiteImage[19]="--video boundary--"; // limite entre deux images sur dcs-900
- int len;
- DWORD pointeur=0;
- DWORD i;
- DWORD n;
- bool flag;
-
- //dc compatible avec mode d'affichage
- hdcSortie = CreateCompatibleDC(0);
-
- // ouverture du socket et envoi de la demande http GET
- // mettre l'adresse de la camera
- sockr=OpenTcpMjpegParser("172.16.186.51",80);
- // requete http à envoyer à la camera pour recevoir le flux MJPEG à adapter à votre camera
- // utiliser un sniffer lors d'une connexion avex IE par exemple
- const char* s = netFormat ("GET /VIDEO.CGI HTTP/1.0\r\nUser-Agent: user\r\nAuthorization: Basic YWRtaW46REVVU1Q=\r\n\r\n") ;
- sockr->send ( s, strlen(s) ) ;
-
- /****************************************************************
- * traitement des informations reçues dans le buffer. Attention *
- * un buffer trop petit entraine la perte de TOUTES les infos *
- * trouve la frontiere entre deux images JPEG *
- *****************************************************************/
-
- while(true) // a faire fin du thread
- {
-
- len=sockr->recv(rbuffer,2048,0);
-
- // si on a reçue quelque chose
- if (len>=0) {
- // traitement un à un des octets reçus
- for (i=0;i<len;i++) {
- image[pointeur++]=rbuffer[i];
- // on ne fait rien tant que l'on à pas reçu au moins 18 octets
- if (pointeur>18) {
- // test limite de l'image dans le flux
- flag=true;
- for (n=0;n<18;n++)
- if (image[pointeur-18+n]==limiteImage[n])
- flag=flag&true;
- else
- flag=false;
-
- if (flag) {
- afficheImage(hWmain, pointeur-18); // 18 pour suppression de la frontiere
- Sleep(50) ;
- pointeur=0;
- }
- }
- } // fin de boucle for lecture du buffer
- }
- }
- CloseTcpMjpegParser(sockr);
- return 0;
- }
-
-
- /* Declare Windows procedure */
- LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT mssg, WPARAM wParam, LPARAM lParam)
-
- {
- switch(mssg)
- {
- case WM_DESTROY:
- DeleteObject(hbmp);
- DeleteDC(hdcSortie);
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, mssg, wParam, lParam);
- }
-
-
-
- /* Make the class name into a global variable */
- char szClassName[ ] = "WindowsApp";
-
- int WINAPI WinMain (HINSTANCE hThisInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpszArgument,
- int nFunsterStil)
-
- {
- // classique programmation de gestion windows (generé par dev c++)
- MSG messages; /* Here messages to the application are saved */
- WNDCLASSEX wincl; /* Data structure for the windowclass */
-
- /* The Window structure */
- wincl.hInstance = hThisInstance;
- wincl.lpszClassName = szClassName;
- wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
- wincl.style = CS_DBLCLKS; /* Catch double-clicks */
- wincl.cbSize = sizeof (WNDCLASSEX);
-
- /* Use default icon and mouse-pointer */
- wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
- wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
- wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
- wincl.lpszMenuName = NULL; /* No menu */
- wincl.cbClsExtra = 0; /* No extra bytes after the window class */
- wincl.cbWndExtra = 0; /* structure or the window instance */
- /* Use Windows's default color as the background of the window */
- wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
-
- /* Register the window class, and if it fails quit the program */
- if (!RegisterClassEx (&wincl))
- return 0;
-
- /* The class is registered, let's create the program*/
- HWND hWnd;
-
- hWnd = CreateWindowEx (
- 0, /* Extended possibilites for variation */
- szClassName, /* Classname */
- "Vision hexapode", /* Title Text */
- WS_OVERLAPPEDWINDOW, /* default window */
- CW_USEDEFAULT, /* Windows decides the position */
- CW_USEDEFAULT, /* where the window ends up on the screen */
- 328, /* The programs width */
- 270, /* and height in pixels */
- HWND_DESKTOP, /* The window is a child-window to desktop */
- NULL, /* No menu */
- hThisInstance, /* Program Instance handler */
- NULL /* No Window Creation data */
- );
- // pas très propre: handle de la fentre commun à tout le programme
- hWmain=hWnd;
-
- /* Make the window visible on the screen */
- ShowWindow (hWmain, nFunsterStil);
-
-
-
- //création du thread (API Windows) de recuperation et d'affichage
- DWORD len=0;
- DWORD total=0;
- DWORD ThreadId;
- HANDLE hThread ;
- DWORD threadID;
- hThread=CreateThread( NULL, 0, TcpMjpegParser, NULL, NULL , &ThreadId);
-
- /* Run the message loop. It will run until GetMessage() returns 0 */
- while (GetMessage (&messages, NULL, 0, 0))
- {
- /* Translate virtual-key messages into character messages */
- TranslateMessage(&messages);
- /* Send message to WindowProcedure */
- DispatchMessage(&messages);
-
- }
-
- /* The program return-value is 0 - The value that PostQuitMessage() gave */
- return messages.wParam;
- }
/******************************************************************
* recuperation d'un flux Mjpeg venant d'une camera IP (DCS-900) *
* 320x200 *
* ouvre une connexion tcp client, envoi une requete http, traite *
* le flux reçu, extrait les images jpeg, les convertit, et *
* affiche le resultat *
******************************************************************
* Copyright 2006 Grimal sylvain *
* utilisation libre pour application non commerciale *
******************************************************************
* linker avec: net ul (plib) libsock32 libgdi32 libuser32 *
* libole32 liboleaut32 libolepro32 libuuid (.a ou .lib selon *
* compilateur) *
******************************************************************/
#include <windows.h>
#include <olectl.h>
#include "include/netsocket.h" // librarie PLIB voir plib.net ou plib.org
#define TCP true
#define UDP false
#define longMaxJpeg 16384 // longueur maximale d'une image jpeg reçue (suffisant pour du 320x200)
unsigned char image[longMaxJpeg];
HWND hWmain;
netSocket *sockr;
// DC d'affichage
HDC hdcSortie;
// Bitmap après convertion du jpeg
HBITMAP hbmp;
/*******************************************************
* convertion d'une image Jpeg en bitmap *
* utilisation ole de windows cf msdn *
*******************************************************/
HBITMAP convertJpegBmp(LPBYTE pmem, DWORD nSize)
{
HRESULT hr;
CoInitialize(0);
HBITMAP hbmp_dst = 0;
// copie image jpeg dans global
HGLOBAL hgbl =(HGLOBAL)GlobalAlloc(GMEM_FIXED, nSize);
memcpy(hgbl, pmem, nSize);
// création du stream d'échange
IStream* stream = 0;
// image jpeg dans global dans stream
hr = CreateStreamOnHGlobal(hgbl, TRUE, &stream);
if(!SUCCEEDED(hr) || !stream) { // si erreur libération des objets déja crées
GlobalFree(hgbl);
CoUninitialize();
} else {
// création d'une 'picture'
IPicture* picture = 0;
// conversion stream vers picture
hr = OleLoadPicture(stream, nSize, 0, IID_IPicture, (void**)&picture);
if(!SUCCEEDED(hr) || !picture) { // si erreur libération des objets déja crées
stream->Release();
GlobalFree(hgbl);
CoUninitialize();
} else {
// recuperation du handle de la 'picture'
HBITMAP hbmp_src;
picture->get_Handle((OLE_HANDLE *)&hbmp_src);
// recuperation du handle du bitmap de la 'picture'
BITMAP bmp;
GetObject(hbmp_src, sizeof bmp, &bmp);
// bmp est le bitmap resultant mais son pointeur vers le contenu pointe vers le contenu de 'picture'
// comme on va dechargé la 'picture' on copie dans une autre zone memoire
hbmp_dst = (HBITMAP)CopyImage(hbmp_src, IMAGE_BITMAP, 0, 0, 0);
picture->Release();
stream->Release();
GlobalFree(hgbl);
CoUninitialize();
}
}
return hbmp_dst;
}
/****************************************************
* affiche une image jpeg contenue dans le tableau *
* image[52 ou 53 à longueur-5] *
****************************************************/
int afficheImage(HWND hwnd, DWORD longueur)
{
HDC hdc;
DWORD debut;
// recherche debut variable selon texte indication taille image
debut=50; // normalement debut=52 si taille<10Ko et 53 si >
while (!((image[debut]==0xFF) & (image[debut+1]==0xD8)) & (debut<54)) {
debut ++;
}
// test entete et fin fichier JPEG
if ((image[debut]==0xFF) & (image[debut+1]==0xD8) &(image[longueur-6]==0xFF)&(image[longueur-5]==0xD9)) {
// conversion de l'image JPEG en Bitmap (ole Windows)
hbmp = convertJpegBmp((LPBYTE) &image[debut], longueur-debut-4);
// et affichage (GDI windows)
hdc = GetDC(hwnd);
SelectObject(hdcSortie, hbmp);
BitBlt(hdc, 0, 0, 320, 240, hdcSortie, 0, 0, SRCCOPY);
ReleaseDC(hwnd,hdc);
// et destruction du bitmap
DeleteObject(hbmp);
}
}
/***************************************************************
* Ouverture d'un socket TCP IP Plib port de sortie *
* geré automatiquement par plib non contrôlable mais avantage *
* gestion automatique si lancement de plusieurs applications *
****************************************************************/
netSocket* OpenTcpMjpegParser(char* ip,unsigned int port)
{
netSocket *sockr;
netInit();
sockr= new netSocket();
sockr->open(TCP);
sockr->connect(ip,port);
return sockr;
}
/***************************************************************
* Fermeture du socket TCP IP *
****************************************************************/
int CloseTcpMjpegParser(netSocket *sockr)
{
sockr->close();
}
/****************************************************************
* routine principale: ouvre une connection TCP/IP entre l'hote *
* (le client) et la camera (le serveur), envoi la demande http *
* *
*****************************************************************/
DWORD WINAPI TcpMjpegParser( void *param)
{
char rbuffer[2048];
char limiteImage[19]="--video boundary--"; // limite entre deux images sur dcs-900
int len;
DWORD pointeur=0;
DWORD i;
DWORD n;
bool flag;
//dc compatible avec mode d'affichage
hdcSortie = CreateCompatibleDC(0);
// ouverture du socket et envoi de la demande http GET
// mettre l'adresse de la camera
sockr=OpenTcpMjpegParser("172.16.186.51",80);
// requete http à envoyer à la camera pour recevoir le flux MJPEG à adapter à votre camera
// utiliser un sniffer lors d'une connexion avex IE par exemple
const char* s = netFormat ("GET /VIDEO.CGI HTTP/1.0\r\nUser-Agent: user\r\nAuthorization: Basic YWRtaW46REVVU1Q=\r\n\r\n") ;
sockr->send ( s, strlen(s) ) ;
/****************************************************************
* traitement des informations reçues dans le buffer. Attention *
* un buffer trop petit entraine la perte de TOUTES les infos *
* trouve la frontiere entre deux images JPEG *
*****************************************************************/
while(true) // a faire fin du thread
{
len=sockr->recv(rbuffer,2048,0);
// si on a reçue quelque chose
if (len>=0) {
// traitement un à un des octets reçus
for (i=0;i<len;i++) {
image[pointeur++]=rbuffer[i];
// on ne fait rien tant que l'on à pas reçu au moins 18 octets
if (pointeur>18) {
// test limite de l'image dans le flux
flag=true;
for (n=0;n<18;n++)
if (image[pointeur-18+n]==limiteImage[n])
flag=flag&true;
else
flag=false;
if (flag) {
afficheImage(hWmain, pointeur-18); // 18 pour suppression de la frontiere
Sleep(50) ;
pointeur=0;
}
}
} // fin de boucle for lecture du buffer
}
}
CloseTcpMjpegParser(sockr);
return 0;
}
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT mssg, WPARAM wParam, LPARAM lParam)
{
switch(mssg)
{
case WM_DESTROY:
DeleteObject(hbmp);
DeleteDC(hdcSortie);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, mssg, wParam, lParam);
}
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
// classique programmation de gestion windows (generé par dev c++)
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
HWND hWnd;
hWnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Vision hexapode", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
328, /* The programs width */
270, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
// pas très propre: handle de la fentre commun à tout le programme
hWmain=hWnd;
/* Make the window visible on the screen */
ShowWindow (hWmain, nFunsterStil);
//création du thread (API Windows) de recuperation et d'affichage
DWORD len=0;
DWORD total=0;
DWORD ThreadId;
HANDLE hThread ;
DWORD threadID;
hThread=CreateThread( NULL, 0, TcpMjpegParser, NULL, NULL , &ThreadId);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
Sources de la même categorie
Sources en rapport avec celle ci
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
capture de flux d une camera IP et detecttion d intrusion physique en c++ [ par mannatheking ]
voilà j ai un projet de fin d'etude qui s intitule capture de flux video d une camera IP et detection d intusion en C++ sur windows.pour le moment je
camera ip + c++ builder 3 [ par pingusfab ]
bonjourvoila je souhaiterai recevoir la video en direct d'une camera ip accesible par un navigateur web par son adresse ipd'apres la doc le peut recup
reception données depuis gprs vers une @ ip fixe [ par zdoucha ]
Salut à tous, Je veux developper une application qui me permet de recuperer une donnée envoyé par un µcontrolleur msc1210 a travers un gprs vers une @
Problem avec les #DEFINE avec winapi en c [ par dyroj ]
Bonjour a tous,je suis en train de créer un programme et avec une interface graphique (winapi) créer par les ressource.j'utilise les DEFINE pour iden
Nslookup pour trouver l'ip [ par dolsky ]
Bonjour,Je cherche à récupérer les adresses IP d'une liste des machines que j'ai sur AD.J'ai le script suivant avec la liste des machine que j'indique
url ip [ par dyroj ]
salut a tous,comment recuperer une ip a partir dune url.++
adresse ip [ par moughite ]
salut tout le monde j'arrive pas a réaliser un programme en c++ qui permet d'afficher les information de la commande (ipconfig) c'est a dire (adresse
Violation d'accès mémoire [ par zoneart ]
Bonjour,Je suis débutant et j'ai écris deux trois lignes de codes que j'aimerais vous soumettre car une erreur de violation d'accès mémoire survient l
|
Téléchargements
Logiciels à télécharger sur le même thème :
Comparez les prix Nouvelle version
|