Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    [C#] Acquisire da Webcam con avicap32.dll

    Ciao a tutti

    Premesso che ho cercato tanti esempi e/o documentazioni, ma
    - Trovo sempre lo stesso codice di esempio che fa sempre la stessa cosa;
    - Il codice di cui sopra è commentato in modo minimo, giusto per farti capire cosa fa in quella determintata riga, senza spiegarti argomenti, parametri, significato di certe costanti e quant'altro;
    - Microsoft come al solito non si spreca in documentazione...

    vi illustro il problema.

    Software semplicissimo, deve fare questo:
    1) Avvia visualizzazione Webcam
    2) Mostrami solo una porzione di immagine (cioè una finestra dentro la finestra webcam, di dimensione e posizione definite dal programma)
    3) Acquisisci una fotografia
    4) Taglia e ridimensiona
    5) Salva in un formato e in un percorso prescelti.

    Ecco la classe che implementa avicap32:
    codice:
    using System;
    using System.Runtime.InteropServices;
    
    namespace PhotoWebcam
    {
        /// <summary>
        /// Modulo per la gestione dei messaggi alla avicap32.dll
        /// </summary>
        public class Capture
        {
            //Di seguito un elenco di variabili necessarie per dialogare con la DLL
    
            public static short WM_CAP = 1024;
            public static long WM_USER = 1024;
    
            public static int WM_CAP_DRIVER_CONNECT = WM_CAP + 10;
            public static int WM_CAP_DRIVER_DISCONNECT = WM_CAP + 11;
            public static int WM_CAP_EDIT_COPY = WM_CAP + 30;
            public static long WM_CAP_FILE_SAVEDIB = WM_USER + 25;
            public static long WM_CAP_FILE_SAVEAS = WM_USER + 23;
    
            public static int WM_CAP_SET_PREVIEW = WM_CAP + 50;
            public static int WM_CAP_SET_PREVIEWRATE = WM_CAP + 52;
            public static int WM_CAP_SET_SCALE = WM_CAP + 53;
            public static int WS_CHILD = 1073741824;
            public static int WS_VISIBLE = 268435456;
            public static short SWP_NOMOVE = 2;
            public static short SWP_NOSIZE = 1;
            public static short SWP_NOZORDER = 4;
            public static short HWND_BOTTOM = 1;
    
            //creiamo delle funzioni che
            //faranno da riferimento a routine esterne della nostra dll
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="hwnd"></param>
            /// <param name="wMsg"></param>
            /// <param name="wParam"></param>
            /// <param name="lParam"></param>
            /// <returns></returns>
            [DllImport("USER32.DLL")]
            public static extern int SendMessageA(
                int hwnd,
                int wMsg,
                int wParam,
                [MarshalAs(UnmanagedType.AsAny)] object lParam
                );
    
            /// <summary>
            /// La funzione cambia la dimensione, posizione, 
            /// e l'ordine della finestra e se in primo piano.
            /// </summary>
            /// <param name="hwnd">Handle della finestra</param>
            /// <param name="hWndInsertAfter">Handle della finestra precede in ordine quella selezionata</param>
            /// <param name="x">Coordinata X</param>
            /// <param name="y">Coordinata Y</param>
            /// <param name="cx">Dimensioni in larghezza</param>
            /// <param name="cy">Dimensioni in Altezza</param>
            /// <param name="wFlags">Specifica le opzioni aggiuntive</param>
            /// <returns>Se ha avuto successo ritorna un valore non zero</returns>
            [DllImport("USER32.DLL")]
            public static extern int SetWindowPos(
                int hwnd,
                int hWndInsertAfter,
                int x,
                int y,
                int cx,
                int cy,
                int wFlags
                );
    
            /// <summary>
            /// Metodo che distrugge una finestra
            /// </summary>
            /// <param name="hwnd">Handle della finestra</param>
            /// <returns>True o false a seconda dell'esito dell'operazione</returns>
            [DllImport("USER32.DLL")]
            public static extern bool DestroyWindow(int hwnd);
    
            /// <summary>
            /// Metodo che dirige il flusso alla finestra di preview
            /// </summary>
            /// <param name="lpszWindowName"></param>
            /// <param name="dwStyle"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <param name="nWidth"></param>
            /// <param name="nHeight"></param>
            /// <param name="hWndParent"></param>
            /// <param name="nID"></param>
            /// <returns></returns>
            [DllImport("AVICAP32.dll")]
            public static extern int capCreateCaptureWindowA(
                string lpszWindowName,
                int dwStyle,
                int x,
                int y,
                int nWidth,
                short nHeight,
                int hWndParent,
                int nID
                );
    
            /// <summary>
            /// Funzione che ritorna l'esistenza o no di un driver
            /// </summary>
            /// <param name="wDriver"></param>
            /// <param name="lpszName"></param>
            /// <param name="cbName"></param>
            /// <param name="lpszVer"></param>
            /// <param name="cbVer"></param>
            /// <returns></returns>
            [DllImport("AVICAP32.dll")]
            public static extern bool capGetDriverDescriptionA(
                short wDriver,
                string lpszName,
                int cbName,
                string lpszVer,
                int cbVer
                );
    
        }
    }
    Punti 1,2,4,5 tutto OK!

    Il punto 3 è un po' più incasinato.
    Io ho una webcam che ha risoluzione massima 800x600, ma il sw deve poter operare con qualsiasi webcam.
    1a domanda: Come faccio a sapere la risoluzione massima della mia webcam?
    Se ridimensiono l'immagine della webcam per farla stare nella mia finestra, quando acquisisco l'immagine, quest'ultima non viene catturata a risoluzione piena, ma nelle dimensioni in cui viene visualizzata. Quindi ciò che fa è solamente un fermo immagine di ciò che visualizza. Ed io invece voglio che mi scatti una foto a risoluzione massima! Qundi:
    2a domanda: Come faccio a scattare una foto a risoluzione massima?

    Il metodo per catture l'immagine all'interno di una picturebox (imgGrab):
    codice:
            private void btnGrab_Click(object sender, EventArgs e)
            {
                    PhotoWebcam.Capture.SendMessageA(hHwnd, Convert.ToInt32(PhotoWebcam.Capture.WM_CAP_EDIT_COPY), 0, 0);
    
                    IDataObject ido = Clipboard.GetDataObject();
    
                    if (ido.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
                    {
                        Bitmap bmpImage = (Bitmap)ido.GetData(System.Windows.Forms.DataFormats.Bitmap);
                        Bitmap bmpCrop = bmpImage.Clone(new Rectangle(-x, -y, imgCam.Width, imgCam.Height), bmpImage.PixelFormat);
    
                        imgGrab.Image = (Image)bmpCrop;
                    }
    
                    Clipboard.Clear();
           }
    Inoltre un altro piccolo problema che fin che lo uso io chissenefrega, ma dato che devo farlo usare ad altri non è il massimo: prima di avviare per la primissima volta la webcam, faccio scegliere all'utente il dispositivo da utilizzare con il seguente codice:
    codice:
            private void LoadDeviceList()
            {
                string strNome = Space(100); // Ho provato anche semplicemente con ""
                string strVer = Space(100);
                bool bReturn;
                short x = 0;
                //carica la lista completa nell'elenco
                do
                {
                    //ricava il nome del driver e la versione
                    bReturn = PhotoWebcam.Capture.capGetDriverDescriptionA(x, strNome, 100, strVer, 100);
                    //se un device lo aggiunge alla lista
                    if (bReturn)
                    {
                        lstDevices.Items.Add(strNome.Trim());
                    }
                    
                    x += 1;
    
                }
                while (bReturn);
    
            }
    Il problema è che invece di vedere i nomi dei dispositivi, vedo righe bianche... quindi io dopo la prima volta ho capito quale era la riga che mi interessava, ma un altro potrebbe trovarsi un po' disorientato (l'elenco sembra vuoto!!)...

    P.S. Ho usato avicap32.dll perchè sul web ho trovato quello, ma se c'è un altro modo va bene lo stesso
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  2. #2
    up
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  3. #3
    nessuno ci capisce qualcosa??

    Il mio problema è solo su come acquisire un immagine a risoluzione massima!

    Il resto è meno importante...
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  4. #4
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,538
    se non sbaglio questa classe funziona direzionando il flusso dalla webcam ad una superfice di win, cio' dovrebbe avvenire già a risoluzione massima della webcam, poi se tu dimensioni la finestra....

    prova a prendere il flusso dei byte di ogni fotogramma e vedrai che ottieni la risoluzione massima

  5. #5
    Originariamente inviato da U235
    se non sbaglio questa classe funziona direzionando il flusso dalla webcam ad una superfice di win, cio' dovrebbe avvenire già a risoluzione massima della webcam, poi se tu dimensioni la finestra....

    prova a prendere il flusso dei byte di ogni fotogramma e vedrai che ottieni la risoluzione massima
    come si fa??
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  6. #6
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,538
    Originariamente inviato da 8matt5
    come si fa??
    ora non ho sottomano quella classe (magari posta tutto), ma ricordo che l'avevo già affrontato questo problema su quella classe.

  7. #7
    La classe Capture l'ho postata per intero
    Posso postare il codice del form
    codice:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace PhotoWebcam
    {
        public partial class captureWindow : Form
        {
            private int hHwnd;
            private short iDevice;
    
            //coordinate e dimensioni originali della PictureBox
            private int ox, oy, ow, oh;
    
            //coordinate e dimensioni della finestra webcam
            private int camW, camH;
            private int camX, camY;
    
            //risoluzione webcam
            int w = 800;
            short h = 600;
            
            public captureWindow()
            {
                InitializeComponent();
                ox = imgCam.Left;
                oy = imgCam.Top;
                ow = imgCam.Width;
                oh = imgCam.Height;
    
                txtFilename.Text = PhotoWebcam.Properties.Settings.Default.defName;
                comboExt.Text = PhotoWebcam.Properties.Settings.Default.defExt;
    
            }
    
            private void btnExit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
    
            private void cmdTrayExit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
            private void impostazioniToolStripMenuItem_Click(object sender, EventArgs e)
            {
                preferWin pref = new preferWin();
                pref.Show(this);
                pref.Focus();
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                avviaWebcam();
            }
    
            private void avviaWebcam()
            {
    
                //Calcolo la dimesione e posizione della finestra
    
                //dimensioni immagine richieste
                int imgLar = PhotoWebcam.Properties.Settings.Default.imgLar;
                int imgAlt = PhotoWebcam.Properties.Settings.Default.imgAlt;
    
                if ((ow / oh) > (imgLar / imgAlt))
                {
                    imgLar = Convert.ToInt32(1.0 * oh * imgLar / imgAlt);
                    imgAlt = oh;
                }
                else
                {
                    imgAlt = Convert.ToInt32(1.0 * ow * imgAlt / imgLar);
                    imgLar = ow;
                }
    
                if ((w / h) > (imgLar / imgAlt))
                {
                    camW = Convert.ToInt32(1.0 * imgAlt * w / h);
                    camH = imgAlt;
                }
                else
                {
                    camW = imgLar;
                    camH = Convert.ToInt32(1.0 * imgLar * h / w);
                }
    
                imgCam.Width = imgLar;
                imgCam.Height = imgAlt;
    
                imgCam.Left = ((gb.Width - imgLar) / 2);
                imgCam.Top = ((gb.Height - imgAlt) / 2);
    
                camX = (imgLar - camW) / 2;
                camY = (imgAlt - camH) / 2;
    
                //imposto il device selezionato
                iDevice = PhotoWebcam.Properties.Settings.Default.intDevice;
                
                if (PhotoWebcam.Capture.capGetDriverDescriptionA(iDevice, "", 100, "", 100))
                {
                    //Dico alla dll di dirigere il flusso alla mia finestra di preview
                    hHwnd = PhotoWebcam.Capture.capCreateCaptureWindowA(iDevice.ToString(), PhotoWebcam.Capture.WS_VISIBLE | PhotoWebcam.Capture.WS_CHILD, camX, camY, w, h, imgCam.Handle.ToInt32(), 0);
    
                    //mi collego al device
                    if (Convert.ToBoolean(PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_DRIVER_CONNECT, iDevice, 0)))
                    {
                        //Imposto la preview
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_SCALE, 1, 0);
    
                        //imposto il rate in millisecondi
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_PREVIEWRATE, 66, 0);
    
                        //Faccio partire la preview
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_PREVIEW, 1, 0);
    
                        //Scalo la preview all'interno della dimensione del mio box immagine
                        PhotoWebcam.Capture.SetWindowPos(hHwnd, PhotoWebcam.Capture.HWND_BOTTOM, camX, camY, camW, camH, PhotoWebcam.Capture.SWP_NOMOVE | PhotoWebcam.Capture.SWP_NOZORDER);
                        
                        btnStart.Enabled = false;
                        btnStop.Enabled = true;
                        btnGrab.Enabled = true;
                        btnGrab.Image = PhotoWebcam.Properties.Resources.camera;
                    }
                    else
                    {
                        //Non è possibile accedere al device
                        PhotoWebcam.Capture.DestroyWindow(hHwnd);
                        System.Windows.Forms.MessageBox.Show(this, "WebCam non impostata.\nScegliere Strumenti -> Preferenze e selezionare un dispositivo","PhotoWebcam");
                    }
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show(this, "WebCam non impostata.\nScegliere Strumenti -> Preferenze e selezionare un dispositivo","PhotoWebcam");
                }
            }
    
            private void btnStop_Click(object sender, EventArgs e)
            {
                //chiudo il flusso
                PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_DRIVER_DISCONNECT, iDevice, 0);
                PhotoWebcam.Capture.DestroyWindow(hHwnd);
                //sblocco i bottoni
                btnStart.Enabled = true;
                btnStop.Enabled = false;
                btnGrab.Enabled = false;
            }
    
            private void btnGrab_Click(object sender, EventArgs e)
            {
                    PhotoWebcam.Capture.SendMessageA(hHwnd, Convert.ToInt32(PhotoWebcam.Capture.WM_CAP_EDIT_COPY), 0, 0);
    
                    IDataObject ido = Clipboard.GetDataObject();
    
                    if (ido.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
                    {
                        Bitmap bmpImage = (Bitmap)ido.GetData(System.Windows.Forms.DataFormats.Bitmap);
                        Bitmap bmpCrop = bmpImage.Clone(new Rectangle(-camX, -camY, imgCam.Width, imgCam.Height), bmpImage.PixelFormat);
    
                        imgGrab.Image = (Image)bmpCrop;
                    }
    
                    Clipboard.Clear();
           }
    
            private void btnSave_Click(object sender, EventArgs e)
            {
                if (txtFilename.Text == "" || txtFilename.Text == null)
                {
                    MessageBox.Show("Inserire un nome per il file", "PhotoWebcam", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
    
                if (imgGrab.Image != null)
                {
                    string percorso = PhotoWebcam.Properties.Settings.Default.defPath;
                    if (!System.IO.Directory.Exists(percorso))
                        System.IO.Directory.CreateDirectory(percorso);
    
                    percorso += "\\" + txtFilename.Text + "." + comboExt.Text;
                    System.Drawing.Imaging.ImageFormat imf;
    
                    switch (comboExt.Text)
                    {
                        case "jpg":
                            imf = System.Drawing.Imaging.ImageFormat.Jpeg;
                            break;
                        case "gif":
                            imf = System.Drawing.Imaging.ImageFormat.Gif;
                            break;
                        case "png":
                            imf = System.Drawing.Imaging.ImageFormat.Png;
                            break;
                        case "bmp":
                            imf = System.Drawing.Imaging.ImageFormat.Bmp;
                            break;
                        default:
                            imf = System.Drawing.Imaging.ImageFormat.Jpeg;
                            break;
                    }
    
                    imgGrab.Image.Save(percorso, imf);
    
                    MessageBox.Show(this, "Immagine salvata!", "PhotoWebcam", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                else
                {
                    MessageBox.Show(this, "Nessuna Immagine", "PhotoWebcam", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                }
            }
    
            private void cancellaToolStripMenuItem_Click(object sender, EventArgs e)
            {
                imgGrab.Image = null;
            }
    
            private void copiaImmagineToolStripMenuItem_Click(object sender, EventArgs e)
            {
                if (imgGrab.Image != null)
                {
                    Clipboard.Clear();
                    Clipboard.SetData(System.Windows.Forms.DataFormats.Bitmap, imgGrab.Image);
                }
            }
    
            private void salvaConNomeToolStripMenuItem_Click(object sender, EventArgs e)
            {
                if (imgGrab.Image != null)
                {
                    SaveFileDialog sfd = new SaveFileDialog();
    
                    sfd.Title = "Salva Immagine con nome";
                    sfd.FileName = PhotoWebcam.Properties.Settings.Default.defName;
                    sfd.Filter = "Immagine JPEG |*.jpg";
                    sfd.Filter += "|Immagine GIF |*.gif";
                    sfd.Filter += "|Immagine PNG |*.png";
                    sfd.Filter += "|Immagine BMP |*.bmp";
    
                    System.Drawing.Imaging.ImageFormat imf;
    
                    if (sfd.ShowDialog(this) == DialogResult.OK)
                    {
                        switch (sfd.FilterIndex)
                        {
                            case 1:
                                imf = System.Drawing.Imaging.ImageFormat.Jpeg;
                                break;
                            case 2:
                                imf = System.Drawing.Imaging.ImageFormat.Gif;
                                break;
                            case 3:
                                imf = System.Drawing.Imaging.ImageFormat.Png;
                                break;
                            case 4:
                                imf = System.Drawing.Imaging.ImageFormat.Bmp;
                                break;
                            default:
                                imf = System.Drawing.Imaging.ImageFormat.Jpeg;
                                break;
                        }
    
                        imgGrab.Image.Save(sfd.FileName, imf);
    
                        MessageBox.Show(this, "Immagine salvata!", "PhotoWebcam", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                    }
                }
                else
                {
                    MessageBox.Show(this, "Nessuna Immagine", "PhotoWebcam", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                }
            }
    
    
        }
    }
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,538
    grazie, stasera li do un occhiata, ora ho poco tempo.

  9. #9
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,538
    //Scalo la preview all'interno della dimensione del mio box immagine
    PhotoWebcam.Capture.SetWindowPos(hHwnd, PhotoWebcam.Capture.HWND_BOTTOM, camX, camY, camW, camH, PhotoWebcam.Capture.SWP_NOMOVE | PhotoWebcam.Capture.SWP_NOZORDER);


    perchè la scali?

  10. #10
    perchè la picturebox che contiene l'immagine è più piccola dell'immagine originale della webcam. Se non lo scalo riuscirei a vedere solo la porzione in alto a sinistra.

    Comunque non avendo documentazione a riguardo mi sono dovuto affidare a codice già fatto e quello ne è un esempio.
    codice:
                        //Imposto la preview
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_SCALE, 1, 0);
    
                        //imposto il rate in millisecondi
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_PREVIEWRATE, 66, 0);
    
                        //Faccio partire la preview
                        PhotoWebcam.Capture.SendMessageA(hHwnd, PhotoWebcam.Capture.WM_CAP_SET_PREVIEW, 1, 0);
    
                        //Scalo la preview all'interno della dimensione del mio box immagine
                        PhotoWebcam.Capture.SetWindowPos(hHwnd, PhotoWebcam.Capture.HWND_BOTTOM, camX, camY, camW, camH, PhotoWebcam.Capture.SWP_NOMOVE | PhotoWebcam.Capture.SWP_NOZORDER);
    Questo pezzo l'ho ricopiato pari pari
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.