IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> ESP32-S3 LVGL http下载B站头像 JPG显示 -> 正文阅读

[网络协议]ESP32-S3 LVGL http下载B站头像 JPG显示

最近在用ESP32S3获取B站JPG头像进行显示。记录一下,开发板链接:

ESP32-S3 LVGL 开发板 人工智能语音识别 人脸识别 触摸 音频-淘宝网 (taobao.com)

直接上代码:

第一种下载方式:

/*

	获取B站头像JPG文件buffer
*/
static esp_err_t face_http_event_handler(esp_http_client_event_t *evt)
{
	static char *output_buffer; // Buffer to store response of http request from event handler
	static int output_len;		// Stores number of bytes read

	switch (evt->event_id)
	{
	case HTTP_EVENT_ERROR:
		ESP_LOGI(TAG, "HTTP_EVENT_ERROR");
		break;
	case HTTP_EVENT_ON_CONNECTED:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
		break;
	case HTTP_EVENT_HEADER_SENT:
		ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
		break;
	case HTTP_EVENT_ON_HEADER:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
		break;
	case HTTP_EVENT_ON_DATA:
		printf("HTTP_EVENT_ON_DATA, len=%d\n", evt->data_len);

		//如果404或者502
		// if (evt->data_len == 150 || evt->data_len == 146)
		// 	return ESP_OK;

		// printf("%.*s\n", evt->data_len, (char *)evt->data);
		// if (!esp_http_client_is_chunked_response(evt->client)) {
		//         // Write out data
		//         printf("%.*s", evt->data_len, (char*)evt->data);
		//     }
		if (!esp_http_client_is_chunked_response(evt->client))
		{
			//ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA  !esp_http_client_is_chunked_response");
			// If user_data buffer is configured, copy the response into the buffer
			if (face_buffer) /*如果已经申请了内存 就直接复制接收到的数据*/
			{

				memcpy(face_buffer + output_len, evt->data, evt->data_len);
			}
			else /*如果没有申请*/
			{
				if (face_buffer == NULL) /*申请一个http长度的内存来保存数据*/
				{
					face_buffer = (char *)malloc(esp_http_client_get_content_length(evt->client));
					output_len = 0;
					if (face_buffer == NULL)
					{
						ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
						return ESP_FAIL;
					}
				}
				memcpy(face_buffer + output_len, evt->data, evt->data_len); //拷贝数据
			}

			output_len += evt->data_len; //记录下载进度
		}

		break;
	case HTTP_EVENT_ON_FINISH:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
		break;
	case HTTP_EVENT_DISCONNECTED:
		ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");

		break;
	}
	return ESP_OK;
}
void get_face_jpg(char *bili_uid)
{

	static esp_http_client_config_t config = {
		.url = "https://whycan.com/files/members/4115/11111.png",//这里是你的B站头像链接
		.event_handler = face_http_event_handler,
		.buffer_size = 3 * 1024,
		.timeout_ms = 4000,
		.path = "/get",
		.transport_type = HTTP_TRANSPORT_OVER_TCP,
	};
	esp_http_client_handle_t client = esp_http_client_init(&config);
	esp_http_client_set_header(client, "Accept", "*/*");
	esp_http_client_set_header(client, "Accept-Encoding", "identity");
	esp_http_client_set_header(client, "User-Agent", "PostmanRuntime/7.24.1");
	esp_http_client_set_header(client, "Connection", "keep-alive");
	esp_http_client_set_header(client, "Content-Type", "application/json");
	// esp_err_t err = esp_http_client_open(client, 0);
	esp_err_t err = esp_http_client_perform(client);
	if (err == ESP_OK)
	{
		ESP_LOGE(TAG, "HTTP GET Status = %d, content_length = %d",
				 esp_http_client_get_status_code(client),
				 esp_http_client_get_content_length(client));
	}
	else
	{
		ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
	}

	esp_http_client_cleanup(client);
}

以上方式是获取一个固定链接的图片存到face_buffer 这个char*里,下一种是先根据B站id来获取头像图片的url,再根据url来获取图片。

B站个人信息API接口:https://api.bilibili.com/x/space/acc/info?mid=59041601

在浏览器里输入以上链接可以看到:

{"code":0,"message":"0","ttl":1,"data":{"mid":59041601,"name":"Kevincoooool","sex":"男","face":"http://i2.hdslb.com/bfs/face/bce14f5e3af4bca480fc7de227986ba304507078.jpg","face_nft":0,"sign":"Jlink DAP OpenMV 淘宝店铺:酷世DIY","rank":10000,"level":5,"jointime":0,"moral":0,"silence":0,"coins":1249,"fans_badge":true,"fans_medal":{"show":true,"wear":false,"medal":null},"official":{"role":0,"title":"","desc":"","type":-1},"vip":{"type":0,"status":0,"due_date":0,"vip_pay_type":0,"theme_type":0,"label":{"path":"","text":"","label_theme":"","text_color":"","bg_style":0,"bg_color":"","border_color":""},"avatar_subscript":0,"nickname_color":"","role":0,"avatar_subscript_url":""},"pendant":{"pid":0,"name":"","image":"","expire":0,"image_enhance":"","image_enhance_frame":""},"nameplate":{"nid":10,"name":"见习偶像","image":"http://i0.hdslb.com/bfs/face/e93dd9edfa7b9e18bf46fd8d71862327a2350923.png","image_small":"http://i2.hdslb.com/bfs/face/275b468b043ec246737ab8580a2075bee0b1263b.png","level":"普通勋章","condition":"所有自制视频总播放数\u003e=10万"},"user_honour_info":{"mid":0,"colour":null,"tags":[]},"is_followed":false,"top_photo":"http://i0.hdslb.com/bfs/space/cb1c3ef50e22b6096fde67febe863494caefebad.png","theme":{},"sys_notice":{},"live_room":{"roomStatus":1,"liveStatus":0,"url":"https://live.bilibili.com/2153512","title":"啥呀这是","cover":"http://i0.hdslb.com/bfs/live/user_cover/20e11be91ed85436a8800dafb3d3550736cb1899.jpg","online":0,"roomid":2153512,"roundStatus":0,"broadcast_type":0},"birthday":"03-08","school":{"name":"成都信息工程大学"},"profession":{"name":""},"tags":null,"series":{"user_upgrade_status":3,"show_upgrade_window":false}}}

其中?"face":"http://i2.hdslb.com/bfs/face/bce14f5e3af4bca480fc7de227986ba304507078.jpg" 就是我们的头像图片链接,再把这个链接放到以上方式的url中即可。

上代码:

esp_err_t cjson_face(char *text)
{
	cJSON *root_ksdiy, *psub_ksdiy;
	char *index = strchr(text, '{');
	printf("face json:%s\n", text);
	if (index == NULL)
	{
		return ESP_FAIL;
	}
	else
	{
		strcpy(text, index);
		root_ksdiy = cJSON_Parse(text);
		if (root_ksdiy != NULL)
		{
			psub_ksdiy = cJSON_GetObjectItem(root_ksdiy, "data");
			if (psub_ksdiy != NULL)
			{
				cJSON *name = cJSON_GetObjectItem(psub_ksdiy, "name");
				wp_fans.name = name->valuestring;
				cJSON *face_url = cJSON_GetObjectItem(psub_ksdiy, "face");
				wp_fans.face_url = face_url->valuestring;
				ESP_LOGI(TAG, "获取头像URL成功 name:%s  face_url:%s\n", wp_fans.name, wp_fans.face_url);
				memset((char *)url_buff, 0, 256);
				sprintf(url_buff, "%s", face_url->valuestring);
				_get_face_url = true;
			}
			else
			{
				_get_face_url = false;
				ESP_LOGI(TAG, "获取头像URL,请检查uid");
			}
		}
		else
		{
			return ESP_FAIL;
		}
		cJSON_Delete(root_ksdiy);
	}
	return ESP_OK;
}
static esp_err_t bilibili_face_http_event_handler(esp_http_client_event_t *evt)
{

	switch (evt->event_id)
	{
	case HTTP_EVENT_ERROR:
		ESP_LOGI(TAG, "HTTP_EVENT_ERROR");
		break;
	case HTTP_EVENT_ON_CONNECTED:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
		break;
	case HTTP_EVENT_HEADER_SENT:
		ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
		break;
	case HTTP_EVENT_ON_HEADER:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
		break;
	case HTTP_EVENT_ON_DATA:
		printf("HTTP_EVENT_ON_DATA, len=%d\n", evt->data_len);

		//如果404或者502
		if (evt->data_len == 150 || evt->data_len == 146)
			return ESP_OK;

		// printf("%.*s\n", evt->data_len, (char *)evt->data);
		cjson_face((char *)evt->data);

		break;
	case HTTP_EVENT_ON_FINISH:
		ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
		break;
	case HTTP_EVENT_DISCONNECTED:
		ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");

		break;
	}
	return ESP_OK;
}
void get_face_url(char *bili_uid)
{

	static char post_url[256] = {0};
	memset((char *)post_url, 0, 256);
	static esp_http_client_config_t config = {
		// .url = "https://api.bilibili.com/x/relation/stat?vmid=59041601&jsonp=jsonp",
		.event_handler = bilibili_face_http_event_handler,
		.buffer_size = 3 * 1024,
		.timeout_ms = 4000,
		.path = "/get",
		.transport_type = HTTP_TRANSPORT_OVER_TCP,
	};
	sprintf(post_url, "https://api.bilibili.com/x/space/acc/info?mid=%s", bili_uid);
	config.url = post_url;
	esp_http_client_handle_t client = esp_http_client_init(&config);
	esp_http_client_set_header(client, "Accept", "*/*");
	esp_http_client_set_header(client, "Accept-Encoding", "identity");
	esp_http_client_set_header(client, "User-Agent", "PostmanRuntime/7.24.1");
	esp_http_client_set_header(client, "Connection", "keep-alive");
	esp_http_client_set_header(client, "Content-Type", "application/json");

	esp_err_t err = esp_http_client_perform(client);
	if (err == ESP_OK)
	{
		ESP_LOGE(TAG, "HTTP GET Status = %d, content_length = %d",
				 esp_http_client_get_status_code(client),
				 esp_http_client_get_content_length(client));
	}
	else
	{
		ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
	}

	esp_http_client_cleanup(client);
}

最后,获取了B站的头像buffer,我们还要显示出来,在这里要使用到lvgl的split jpg库并对库做一些修改,因为原来的库是不会缩放jpg的,我们得到的头像buffer一般比较大,显示出来整个屏幕都没了,所以需要缩小,

?

.H文件中增加以下define:

/*********************
 *      DEFINES
 *********************/

/* Scaling factor */
// #define LV_TJPGD_CONFIG_SCALING_FACTOR_NONE
//#define LV_TJPGD_CONFIG_SCALING_FACTOR_1_2
#define LV_TJPGD_CONFIG_SCALING_FACTOR_1_4
//#define LV_TJPGD_CONFIG_SCALING_FACTOR_1_8

/* When setting scaling factor to none we should set JD_USE_SCALE to 0
 * set it to 1 otherwise */
#if defined (LV_TJPGD_CONFIG_SCALING_FACTOR_NONE)
    #define LV_TJPGD_SCALING_FACTOR     0
    #define LV_TJPGD_SCALING_FACTOR_DIV 1
#elif defined (LV_TJPGD_CONFIG_SCALING_FACTOR_1_2)
    #define LV_TJPGD_SCALING_FACTOR     1
    #define LV_TJPGD_SCALING_FACTOR_DIV 2
#elif defined (LV_TJPGD_CONFIG_SCALING_FACTOR_1_4)
    #define LV_TJPGD_SCALING_FACTOR     2
    #define LV_TJPGD_SCALING_FACTOR_DIV 4
#elif defined (LV_TJPGD_CONFIG_SCALING_FACTOR_1_8)
    #define LV_TJPGD_SCALING_FACTOR     3
    #define LV_TJPGD_SCALING_FACTOR_DIV 8
#else
    #error "Invalid TJPGD scaling factor configuration"
#endif // defined

?最后显示:

   
lv_img_dsc_t bili_face = {
    .header.always_zero = 0,
    .header.w = 300,
    .header.h = 300,
    .data_size = 300 * 300 * 2,
    .header.cf = LV_IMG_CF_RAW,
    .data = NULL,
};


    img_face = lv_img_create(scr_body, NULL);
    lv_obj_add_style(img_face, LV_IMG_PART_MAIN, &style_img);
    lv_obj_set_pos(img_face, APP_WIN_WIDTH / 2 - 40, 70);


    bili_face.data = (uint8_t *)face_buffer;//把在线获取的buffer给img

    lv_img_set_src(img_face, &bili_face);

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-01 18:03:38  更:2021-12-01 18:05:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:27:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码