不使用GoCV实现Golang摄像头调用
不使用GoCV实现Golang摄像头调用 是否有办法编写不使用GoCV的Go代码来调用摄像头、拍摄照片和视频?我发现了go-webcam,但它仅支持Linux。我需要在Windows 10设备上运行。谢谢。
1 回复
更多关于不使用GoCV实现Golang摄像头调用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,可以通过调用系统API实现。在Windows上可以使用DirectShow接口,这里提供一个使用github.com/blackjack/webcam包的示例,它支持Windows和Linux:
package main
import (
"fmt"
"image/jpeg"
"os"
"time"
"github.com/blackjack/webcam"
)
func main() {
// 获取摄像头列表
cams, err := webcam.ListWebcams()
if err != nil {
panic(err)
}
// 选择第一个摄像头
cam, err := webcam.Open(cams[0])
if err != nil {
panic(err)
}
defer cam.Close()
// 设置格式和分辨率
format := webcam.PixelFormat(webcam.PixelFmtMJPEG)
width, height := uint32(640), uint32(480)
err = cam.StartStreaming(format, width, height)
if err != nil {
panic(err)
}
// 拍摄照片
timeout := uint32(5) // 5秒超时
frame, err := cam.ReadFrame(timeout)
if err != nil {
panic(err)
}
// 保存为JPEG
img, err := cam.Decode(frame, format, width, height)
if err != nil {
panic(err)
}
file, _ := os.Create("photo.jpg")
defer file.Close()
jpeg.Encode(file, img, nil)
fmt.Println("照片已保存为 photo.jpg")
// 录制视频(示例:录制5秒)
videoFile, _ := os.Create("video.mjpeg")
defer videoFile.Close()
start := time.Now()
for time.Since(start) < 5*time.Second {
frame, err := cam.ReadFrame(timeout)
if err != nil {
break
}
videoFile.Write(frame)
}
fmt.Println("视频已保存为 video.mjpeg")
}
对于更完整的Windows支持,可以使用github.com/kbinani/screenshot配合github.com/vova616/screenshot:
package main
import (
"image/png"
"os"
"github.com/kbinani/screenshot"
)
func main() {
// 获取所有显示器的截图(可作为摄像头替代方案)
n := screenshot.NumActiveDisplays()
for i := 0; i < n; i++ {
bounds := screenshot.GetDisplayBounds(i)
img, err := screenshot.CaptureRect(bounds)
if err != nil {
panic(err)
}
fileName := fmt.Sprintf("display_%d.png", i)
file, _ := os.Create(fileName)
defer file.Close()
png.Encode(file, img)
}
}
如果需要直接调用Windows API,可以使用syscall包调用ole32.dll和strmiids.dll:
package main
import (
"syscall"
"unsafe"
)
var (
ole32 = syscall.NewLazyDLL("ole32.dll")
coInitialize = ole32.NewProc("CoInitialize")
coUninitialize = ole32.NewProc("CoUninitialize")
)
func main() {
// 初始化COM库
coInitialize.Call(0)
defer coUninitialize.Call()
// 这里可以继续调用DirectShow API
// 需要导入相应的Windows头文件定义
}
注意:直接调用Windows API需要处理大量CGO交互和COM对象管理。建议使用现有的封装库,如github.com/AllenDang/w32或github.com/lxn/win来简化调用。

