如何在 Windows 上使用 ctypes 在 Python 中捕获网络摄像头照片?

问题描述 投票:0回答:1

我不想使用标题中提到的三个库中的任何一个,因为这三个库都很大,而且我想将我的程序编译成二进制文件,使用这些库中的任何一个都会导致输出达到 100MB 或更多,当我仅使用这些库的一项功能。

我知道可以使用 c/++ 拍摄照片,但我对低级编程语言一无所知。所以我希望得到帮助。

注意:如果有人知道如何在 C/++ 中执行此操作但不知道 ctypes,没问题,只需将其发布在这里,我可以将其更改为 python ctypes 语法。

python c windows ctypes webcam
1个回答
0
投票

您使用哪个操作系统?我添加了一个示例来打开 /dev/video0 并使用内置的 V4L2 在 Linux 上捕获帧(我不熟悉 Windows 替代方案)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <sys/mman.h>

int main() {
    int fd = open("/dev/video0", O_RDWR);  // Open the video device
    if (fd == -1) {
        perror("Opening video device");
        return 1;
    }

    struct v4l2_capability cap;
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
        perror("Querying Capabilities");
        return 1;
    }

    struct v4l2_format fmt;
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = 640;
    fmt.fmt.pix.height = 480;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;  // Set format to MJPEG
    fmt.fmt.pix.field = V4L2_FIELD_NONE;
    
    if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
        perror("Setting Pixel Format");
        return 1;
    }

    struct v4l2_requestbuffers req;
    req.count = 1;  // Request a single buffer
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
        perror("Requesting Buffer");
        return 1;
    }

    struct v4l2_buffer buf;
    memset(&buf, 0, sizeof(buf));
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = 0;

    if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
        perror("Querying Buffer");
        return 1;
    }

    void* buffer = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);

    if (buffer == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    if (ioctl(fd, VIDIOC_STREAMON, &buf.type) == -1) {
        perror("Stream On");
        return 1;
    }

    // Queue the buffer
    if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
        perror("Queue Buffer");
        return 1;
    }

    // Dequeue the buffer
    if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
        perror("Dequeue Buffer");
        return 1;
    }

    FILE* out = fopen("capture.jpg", "wb");
    if (!out) {
        perror("Cannot open image");
        return 1;
    }

    fwrite(buffer, buf.bytesused, 1, out);  // Save buffer to JPEG
    fclose(out);

    munmap(buffer, buf.length);
    close(fd);

    return 0;
}

© www.soinside.com 2019 - 2024. All rights reserved.