Click here to Skip to main content
15,912,072 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I want to set resolution of web cam.
My code is
C#
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
public uint biSize;
public int biWidth;
public int biHeight;
public ushort biPlanes;
public ushort biBitCount;
public uint biCompression;
public uint biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public uint biClrUsed;
public uint biClrImportant;
}
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFO
{
public BITMAPINFOHEADER bmiHeader;
public int bmiColors;
}
public class Avicap32
{
[DllImport("avicap32.dll")]
public extern static IntPtr capGetDriverDescription(ushort index, StringBuilder name, int nameCapacity, StringBuilder description, int descriptionCapacity);
[DllImport("avicap32.dll")]
public extern static IntPtr capCreateCaptureWindow(string title, uint style, int x, int y, int width, int height, IntPtr window, int id);
[DllImport("avicap32.dll")]
public extern static bool capDriverGetName(IntPtr deviceHandle, StringBuilder Drivername, byte size);
[DllImport("avicap32.dll")]
public extern static UInt32 capGetVideoFormat(IntPtr deviceHandle,ref  BITMAPINFO m_bitmapinfo, byte size);
[DllImport("avicap32.dll")]
public extern static bool capSetVideoFormat(IntPtr deviceHandle,ref BITMAPINFO m_bitmapinfo, byte size);
[DllImport("avicap32.dll" ,EntryPoint="capCaptureAbort")]
public extern static bool capCaptureAbort(IntPtr deviceHandle);
[DllImport("avicap32.dll" ,EntryPoint="capCaptureStop")]
public extern static bool capCaptureStop(IntPtr deviceHandle);
public class Constants
{
public const uint WM_CAP = 0x400;
public const uint WM_CAP_DRIVER_CONNECT = 0x40a;
public const uint WM_CAP_DRIVER_DISCONNECT = 0x40b;
public const uint WM_CAP_EDIT_COPY = 0x41e;
public const uint WM_CAP_SET_PREVIEW = 0x432;
public const uint WM_CAP_SET_OVERLAY = 0x433;
public const uint WM_CAP_SET_PREVIEWRATE = 0x434;
public const uint WM_CAP_SET_SCALE = 0x435;
public const uint WS_CHILD = 0x40000000;
public const uint WS_VISIBLE = 0x10000000;
}
public   const int WM_CAP_START = 1024; // WM_USER
public const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;
public const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
public const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
public const int WM_CAP_DLG_VIDEODISPLAY = WM_CAP_START + 42;
public const int WM_CAP_GET_VIDEOFORMAT = WM_CAP_START + 44;
public const int WM_CAP_SET_VIDEOFORMAT = WM_CAP_START + 45;
public const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
public const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
public const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
public const int WM_CAP_GRAB_FRAME_NOSTOP = WM_CAP_START + 61;

[DllImport("user32", EntryPoint = "SendMessage")]
public static extern int SendBitmapMessage(IntPtr hWnd, uint wMsg, int wParam, ref BITMAPINFO lParam);



public void Attach(System.Windows.Forms.Control control)
{
deviceHandle = capCreateCaptureWindow("", Constants.WS_VISIBLE | Constants.WS_CHILD, 0, 0,control.Width,control.Height, control.Handle, 0);
bInfo=new SystemDLL.User32.BITMAPINFO();
bInfo.bmiHeader = new BITMAPINFOHEADER();
if (SendMessage(deviceHandle, Constants.WM_CAP_DRIVER_CONNECT, (IntPtr)deviceNumber, (IntPtr)0).ToInt32() > 0)
{
SendMessage(deviceHandle, Constants.WM_CAP_SET_SCALE, (IntPtr)(-1), (IntPtr)0);
SendMessage(deviceHandle, Constants.WM_CAP_SET_PREVIEWRATE, (IntPtr)0x42, (IntPtr)0);
SendMessage(deviceHandle,Constants.WM_CAP_SET_PREVIEW, (IntPtr)(-1), (IntPtr)0);
bInfo=new BITMAPINFO();
bInfo.bmiHeader = new BITMAPINFOHEADER();
SendBitmapMessage(deviceHandle, WM_CAP_GET_VIDEOFORMAT, Marshal.SizeOf(bInfo), ref bInfo);
bInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(bInfo.bmiHeader);
bInfo.bmiHeader.biWidth = control.Width;
bInfo.bmiHeader.biHeight = control.Height;
SendBitmapMessage(deviceHandle, WM_CAP_SET_VIDEOFORMAT, Marshal.SizeOf(bInfo), ref bInfo);
    
SetWindowPos(deviceHandle, new IntPtr(1), 0, 0,control.Width ,control.Height, 6);
}
else
{
MessageBox.Show("Webcam not found ");
DestroyWindow(deviceHandle);
}
}

C#
SendBitmapMessage(deviceHandle, WM_CAP_GET_VIDEOFORMAT, Marshal.SizeOf(bInfo), ref bInfo);

is working fine but
C#
SendBitmapMessage(deviceHandle, WM_CAP_SET_VIDEOFORMAT, Marshal.SizeOf(bInfo), ref bInfo);
does not work.(why?)
Posted

1 solution

It is not only biWidth and biHeight necessary to set for the resolution change.
In additionally to parameters which require to change (this in case you uses the format which you get previously) you should set the biSizeImage = biWidth * biHeight * biBitCount / 8.
Note: you can't set the resolution you like bcs driver may not support it, at least I suggset you to have with be 16 aligned and height 4 aligned.
You may better to try to use DirectShow as in there you available to determine and enumerate available formats of output.

Regards,
Maxim.
 
Share this answer
 
Comments
Member 7909353 25-Mar-13 6:10am    
bInfo.bmiHeader.biSizeImage =(uint) (control.Width * control.Height * bInfo.bmiHeader.biBitCount) / 8;
does not get work
Maxim Kartavenkov 25-Mar-13 6:13am    
Are you sure that Width and Height is accepted by the capture driver?
Maxim Kartavenkov 25-Mar-13 6:38am    
Try to call WM_CAP_DLG_VIDEOFORMAT and specify one of resolution value from that dialog in your code.
RobbKirk 4-Aug-15 4:41am    
I think your capture device driver doesn't support that format.
My version is: until you don't have native driver for the particular camera, you would have that problem, because VFW by default works with YUY (YUY2) format.
Therefore, the better choice is to manage GET_FORMAT and accept it as the best format for the camera without native driver.
And transform data from comming back grab image into your format.
So you need YUV (YUY) conversion to BMP.
The bad example (according to author opinion) is here: http://www.experts-exchange.com/Hardware/Peripherals/Q_24622577.html

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900