《迅为开发板i.MX8MM 学习记录》——【MIPI篇】Linux 应用程序显示一张图片

2023-11-10


前言

本篇记录:如何在linux应用层开发一个APP,在开发板显示一张指定的图片。


一、准备工作

1.开发环境

  • 虚拟机环境为Ubuntu16.04,安装了交叉编译器 aarch64-poky-linux-gcc。
  • 开发板为迅为i.MX8MM,使用的屏幕是 7.0寸MIPI屏 ,烧录的文件系统是yocto。
  • 正常编译uboot,kernel,dtbs,yocto后,下载到开发板,uboot启动并设置MIPI屏工作。
  • 此时开发板正常显示yocto系统界面,准备工作OK!
  • 以上都是开发板使用手册的教程内容

2.文件准备

  • 在虚拟机下合适目录下创建目录/test ,并在/test目录下创建app.capp.h文件。
  • 准备一张像素尺寸为1280*800testpic.png 的图片,利用工具或网页将其转化为.bmp格式,保存到/test目录下。

二、伪代码分析

思路:将图片读取到数组中,然后打开DRM设备填充/dev/fb0进行显示。
先伪代码形式分析,最后贴出完整代码!

1.读取图片数据到数组

bmp格式的图片文件的头部包含了一些info数据,这些数据并不是真正的显示画面内容,送到framebuffer中是没有用的,会导致整个显示不正确。因此用二进制打开图片后,需要先将头部的info数据进行剔除,留下干净的显示像素信息。
伪代码形式分析

int bmp2fb_buff(uint8_t *r_buff, uint32_t r_size, const char *bmp_path)
{
	/* 二进制打开文件*/
 	fp = fopen( bmp_path, "rb" );
 	/* 提取图片头部信息*/
 	/* ....*/
 	/* 跳转到数据区*/
 	fseek(fp, offsets, SEEK_SET);
 	/* 读取真实图片数据*/
 	fread(buf,1,total_length,fp);
 	/* bmp倒叙转换到数组*/
    cursor_bitmap_format_convert(r_buff, bmp_buf);
	return 0;
}

这里有一个很重要概念,bmp图片数据存储方式是从下到上的,是倒着存放的,因此需要使用 cursor_bitmap_format_convert()函数数据倒置装入framebuffer.

2.打开DRM设备,创建fb

接下来就是使用libdrm库,操作drm设备创建显示缓冲区fb,详细可参考 最简单的DRM应用程序

int main(int argc, char **argv)
{
	/* 打开drm设备*/
	fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
	/* 获取设配 crtc/encoder/connector id */
	res = drmModeGetResources(fd);
	/*	获得 connector*/
	conn = drmModeGetConnector(fd, conn_id);
	/* 为 CRTC 创建扫描帧缓冲区 --> framebuffer*/
	modeset_create_fb(fd, &buf);
	/* Set a CRTC configuration,开始显示输出显示*/
	drmModeSetCrtc(fd, crtc_id, buf.fb_id,
			0, 0, &conn_id, 1, &conn->modes[0]);
}

3.填充framebuffer

	/* 绘制图片将fb区填充图片数组 */
	memcpy(frame_buf->vaddr, g_screen_buff, frame_buf->size);

三、完整代码

使用完整代码前请阅读【一、准备工作】

1.app.h

#ifndef __APP_H
#define __APP_H

/* 构建一个结构体,用于存放DRM KMS配置的参数*/
struct buffer_object {
	uint32_t width;
	uint32_t height;
	uint32_t pitch;
	uint32_t handle;	//
	uint32_t size;
	uint32_t *vaddr;
	uint32_t fb_id;
};

//14byte文件头
typedef struct
{
    char    cfType[2];//文件类型,"BM"(0x4D42)
    int     cfSize;//文件大小(字节)
    int     cfReserved;//保留,值为0
    int     cfoffBits;//数据区相对于文件头的偏移量(字节)
}__attribute__((packed)) BITMAPFILEHEADER; //告诉编译器取消结构在编译过程中的优化对齐

 
//40byte信息头
typedef struct
{
    char ciSize[4];//BITMAPFILEHEADER所占的字节数
    int  ciWidth;//宽度
    int  ciHeight;//高度
    char ciPlanes[2];//目标设备的位平面数,值为1
    int  ciBitCount;//每个像素的位数
    char ciCompress[4];//压缩说明
    char ciSizeImage[4];//用字节表示的图像大小,该数据必须是4的倍数
    char ciXPelsPerMeter[4];//目标设备的水平像素数/米
    char ciYPelsPerMeter[4];//目标设备的垂直像素数/米
    char ciClrUsed[4]; //位图使用调色板的颜色数
    char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
}__attribute__((packed)) BITMAPINFOHEADER;
 
typedef struct
{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    unsigned char reserved;
}__attribute__((packed)) PIXEL;//颜色模式RGB

#endif //__APP_H

2.app.c

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <linux/fb.h>

#include "app.h"

/* 
 	DRM 设备应用程序实现步骤
	1.打开 DRM 设备	     
 	2.查找适配的'crtc +  encoder + connector'
	3.为 CRTC 创建扫描帧缓冲区
	4. KMS 模式配置
	5.绘制图像
*/
#define PER_PIXEL_BYTES     4  					//一个像素点4个字节
#define SCREEN_BUFF_SIZE 	(1280*800*4)			//u32计算
uint8_t g_screen_buff[SCREEN_BUFF_SIZE];	    //屏幕是1280*800大小,每个pixel由4字节组成,实际只有3字节24位,这里用uint32_t存储即可
 
BITMAPFILEHEADER FileHead;
BITMAPINFOHEADER InfoHead;
 
static char *fbp = 0;
static int xres = 0;
static int yres = 0;
static int bits_per_pixel = 0;
int width, height;
int fbfd = 0;

/* bmp数据倒叙转换*/
static int cursor_bitmap_format_convert(char *dst,char *src)
{
    int i ,j ,k;
    char *psrc = src ;
    char *pdst = dst;
    char *p = psrc;
 
    /* 由于bmp存储是从后面往前面,所以需要倒序进行转换 */
    pdst += (width * height * PER_PIXEL_BYTES);
    for(i=0;i<height;i++){
        p = psrc + (i+1) * width * PER_PIXEL_BYTES;
        for(j=0;j<width;j++){
            pdst -= PER_PIXEL_BYTES;    //Damon modify
            p -= PER_PIXEL_BYTES;       //Damon modify
            for(k=0;k<PER_PIXEL_BYTES;k++)
            {
               pdst[k] = p[k]; //Damon modify
            }
        }
    }
    return 0;
}


int bmp2fb_buff(uint8_t *r_buff, uint32_t r_size, const char *bmp_path)
{

	int i;
    FILE *fp;
    int rc;
    char *bmp_buf = NULL;
    char *buf = NULL;
    int flen = 0;
    int ret = -1;
    int total_length = 0;

    if(bmp_path == NULL)
    {
        printf("bmp_path Error,return\n");
        return -1;
    }
    printf("img path = %s\n", bmp_path);
    fp = fopen( bmp_path, "rb" );
    if(fp == NULL){
        printf("load cursor file open failed\n");
        return -1;
    }

    /* 求解文件长度 */
    fseek(fp,0,SEEK_SET);
    fseek(fp,0,SEEK_END);
 
    flen = ftell(fp);
    
    bmp_buf = (char*)calloc(1,flen - 54);
    if(bmp_buf == NULL){
        printf("load > malloc bmp out of memory!\n");
        return -1;
    }
 
    /* 再移位到文件头部 */
    fseek(fp,0,SEEK_SET);
 
    rc = fread(&FileHead, sizeof(BITMAPFILEHEADER),1, fp);
    if ( rc != 1)
    {
        printf("read header error!\n");
        fclose( fp );
        return( -2 );
    }
 
    //检测是否是bmp图像
    if (memcmp(FileHead.cfType, "BM", 2) != 0)
    {
        printf("it's not a BMP file\n");
        fclose( fp );
        return( -3 );
    }

    //获取Info
    rc = fread( (char *)&InfoHead, sizeof(BITMAPINFOHEADER),1, fp );
    if ( rc != 1)
    {
        printf("read infoheader error!\n");
        fclose( fp );
        return( -4 );
    }

    width = InfoHead.ciWidth;
    height = InfoHead.ciHeight;
    total_length = width * height * PER_PIXEL_BYTES;

    printf("file info:\n");
    printf("\t image size:\t%d\n", flen);               //图片大小
    printf("image info:\n");
    printf("\t image size:\t%d\n",FileHead.cfSize);      //文件大小  
    printf("\t image pixel:\twidth=%d ,height=%d\n", InfoHead.ciWidth, InfoHead.ciHeight);
    printf("\t pixel bits:\t%d\n", InfoHead.ciBitCount); //
    printf("\t buffer bytes:\t%d\n", total_length);     //

    //跳转的数据区
    fseek(fp, FileHead.cfoffBits, SEEK_SET);//fb 从SEEK_SET跳转cfoffBits字节

	//读取bmp数据
    buf = bmp_buf;
    while ((ret = fread(buf,1,total_length,fp)) >= 0) {
        if (ret == 0) {
            usleep(100);
            continue;
        }
        printf("\t read bytes:\t%d\n", ret);
        buf = ((char*) buf) + ret;
        total_length = total_length - ret;
        if(total_length == 0)
            break;
    }
 
	//bmp倒叙转换到数组
    cursor_bitmap_format_convert(r_buff, bmp_buf);

	//内存释放
    free(bmp_buf);
    fclose(fp);
    return 0;
}


/* 创建fb缓存,显示图片*/
static int modeset_create_fb(int fd, struct buffer_object *frame_buf)
{
	struct drm_mode_create_dumb dumb_buf = {};	//创建显示缓存 显存
 	struct drm_mode_map_dumb dum_map = {};		//映射到内存空�?

	uint8_t depth = 24;		//每个通道的每个像素分量的有效比特数
	uint8_t bpp = 32;		//bit per pixel 指每个像素所占用的有效比特数
	uint32_t i;

	/* create a dumb-buffer, the pixel format is XRGB888 */
	dumb_buf.width = frame_buf->width;
	dumb_buf.height = frame_buf->height;
	dumb_buf.bpp = bpp;
	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb_buf);

	/* bind the dumb-buffer to an FB object */
	frame_buf->pitch = dumb_buf.pitch;
	frame_buf->size = dumb_buf.size;
	frame_buf->handle = dumb_buf.handle;
	drmModeAddFB(fd, frame_buf->width, frame_buf->height, depth, bpp, frame_buf->pitch,
			   frame_buf->handle, &frame_buf->fb_id);

	/* map the dumb-buffer to userspace */
	dum_map.handle = dumb_buf.handle;
	drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &dum_map);

	frame_buf->vaddr = mmap(0, dumb_buf.size, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, dum_map.offset);

	/* 绘制图片将fb区填充图片数组 */
	memcpy(frame_buf->vaddr, g_screen_buff, frame_buf->size);
	// for (i = 0; i < (frame_buf->size/4 ); i++)
	// {
    //     frame_buf->vaddr[i] = pic_buff[i];
	// }
	return 0;
}

/* 销毁fb 缓存*/
static void modeset_destroy_fb(int fd, struct buffer_object *frame_buf)
{
	struct drm_mode_destroy_dumb destroy = {};

	drmModeRmFB(fd, frame_buf->fb_id);

	munmap(frame_buf->vaddr, frame_buf->size);

	destroy.handle = frame_buf->handle;
	drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
}

int main(int argc, char **argv)
{
	struct buffer_object buf;

	int fd;
	int ret;
	drmModeConnector *conn;
	drmModeRes *res;
	uint32_t conn_id;
	uint32_t crtc_id;

    //读取图片,处理成fb数组
	bmp2fb_buff(g_screen_buff,SCREEN_BUFF_SIZE,"./testpic.bmp");  //bmp图片转换为g_screen_buff
   
	/* 打开drm设备*/
	fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
	if(fd<0)
	{
		printf("open card0 failed!\n");
	}
	
	/* 获取设配 crtc/encoder/connector id */
	res = drmModeGetResources(fd);
	crtc_id = res->crtcs[0];
	conn_id = res->connectors[0];
	printf("crtc id=%d\n",crtc_id);
	printf("crtc id=%d\n",conn_id);


	/*	获得 connector*/
	conn = drmModeGetConnector(fd, conn_id);
	buf.width = conn->modes[0].hdisplay;
	buf.height = conn->modes[0].vdisplay;
	printf("buf width=%d\n",buf.width);
	printf("buf height=%d\n",buf.height);


	/* 为 CRTC 创建扫描帧缓冲区 --> framebuffer*/
	modeset_create_fb(fd, &buf);

	/* Sets a CRTC configuration,这之后就会开始在 crtc0 + connector0 pipeline 上进行以 mode0 输出显示*/
	drmModeSetCrtc(fd, crtc_id, buf.fb_id,
			0, 0, &conn_id, 1, &conn->modes[0]);

	
	
	getchar(); //Enter 退出
	modeset_destroy_fb(fd, &buf);
	drmModeFreeConnector(conn);
	drmModeFreeResources(res);
	close(fd);

	return 0;
}

四、编译与运行

图片文件准备好以后,代码也写好后,Ubuntu中的目录结构如下

/test
	--app.c
	--app.h
	--testpic.bmp

1.编译

bmp/目录下顺序执行以下命令,使用交叉编译器编译app.c

  • export ARCH=arm64
  • . /opt/fsl-imx-xwayland/4.14-sumo/environment-setup-aarch64-poky-linux
  • aarch64-poky-linux-gcc app.c -I/usr/include/drm/ -ldrm -o app --sysroot=/opt/fsl-imx-xwayland/4.14-sumo/sysroots/aarch64-poky-linux

交叉编译命令与【迅为开发指南】给出的有一些不一致,原因是因为使用交叉编译器编译使用libdrm库的app.c文件时会报错:找不到include <drm.h>头文件,于是在编译指令中加入了-I/usr/include/drm/ -ldrm

2.运行

  • 开发板上使用killall weston命令杀死yocto占用的屏幕进程,建议执行多次。
  • /test文件夹整个拷贝到开发板合适目录下,比如nfs服务绑定目录/mnt下,运行./app

拷贝整个文件夹的目的:如果开发板使用wifi 利用 nfswindows 进行文件共享,那么传输testpic.bmp资源需要花费一段时间,可能导致图片显示不出来。

五、总结

本文参考文章:

感谢两位高人的代码!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《迅为开发板i.MX8MM 学习记录》——【MIPI篇】Linux 应用程序显示一张图片 的相关文章

  • 如何将动态链接的应用程序转换为静态链接的应用程序?

    我有一个应用程序 例如 gedit 它是动态链接的 但我没有源代码 所以我不能按我喜欢的方式编译它 我想要做的是将其静态链接并将其移动到没有运行该应用程序所需的库的系统 那么是否可以做到以及如何做到呢 理论上是可能的 您基本上必须执行与动态
  • 字符串常量之前的预期标识符

    有一个这样的程序 include
  • 如何使用Python distutils?

    我用 python 编写了一个快速程序 将 gtk GUI 添加到 cli 程序中 我想知道如何使用 distutils 创建安装程序 因为它只是命令行应用程序的 GUI 前端 所以它只能在 nix 中工作 所以我不担心它是跨平台的 我的主
  • Linux 上共享内存的生命周期是多长

    我正在使用 ftok shmget shmat shmdt 函数在 Linux 上创建 写入和读取共享段 如果我写入一个程序中的段 然后退出 然后稍后从另一个程序中读取该段 我会惊讶地发现数据仍然存在 我预计当共享一个段的最后一个进程执行
  • 将条目添加到 Linux 内核 .config 文件

    如何手动将 CONFIG XILINX FIXED DEVTREE ADDR y 行添加到 Linux 配置文件中 当我构建内核时它不断被覆盖 您可以通过以下方式构建make CONFIG XILINX FIXED DEVTREE ADDR
  • 在詹金斯管道作业中将变量传递给bash脚本

    我有一个 Jenkins 管道作业 其中我使用名为 setup sh 的 bash 脚本配置我的环境 如下所示 bin bash export ARCH 1 echo architecture ARCH 在 Jenkins 管道脚本中 我使
  • 如何在 Linux 上正确地将网络接口置于混杂模式

    那么如何正确地做到这一点呢 我知道如何通过创建套接字 然后使用 ioctl 设置 IFF PROMISC 标志来做到这一点 如 如何在C中检查网络设备状态 https stackoverflow com questions 3055622
  • Python select() 行为很奇怪

    我在理解 select select 的行为时遇到一些困难 请考虑以下 Python 程序 def str to hex s def dig n if n gt 9 return chr 65 10 n else return chr 48
  • SDL/C++ OpenGL 程序,如何阻止 SDL 捕获 SIGINT

    我在用SDL http www libsdl org 用于在 Linux 上运行的 OpenGL 应用程序 我的问题是 SDL 正在捕获 SIGINT 并忽略它 这是一个痛苦 因为我正在通过屏幕会话进行开发 并且我无法使用 CTRL C 终
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • ngx_http_brotli_filter_module.so" 与 /etc/nginx/nginx.conf:1 中的二进制不兼容

    Using Nginx 1 17 3 and Nginx 1 14 0在两台独立服务器上的 Ubuntu 18 上 两者都显示相同的错误ngx http brotli filter module so is not binary compa
  • java轻量级调试器[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个轻量级的 java 调试器 无论是在 IDE 中还是独立的 命令行或 GUI 中 我正在使用 ant 和 vim 并且尝试过
  • 复制稀疏文件

    我正在尝试了解 Linux UNIX 低级接口 作为练习 我想编写一个代码 将一个有漏洞的文件复制到一个新文件 同样有漏洞 所以我的问题是 如何从第一个文件读取 而不是直到第一个洞 而是直到文件的最后 如果我没错的话 read 当到达第一个
  • 为什么运行一个空程序需要这么多指令?

    所以最近我了解到perfLinux 中的命令 我决定进行一些实验 因此我创建了一个空的 C 程序并测量了运行所需的指令数 echo int main gt emptyprogram c gcc O3 emptyprogram c o emp
  • 如何从 Windows 反编译 Linux 二进制文件?

    如何从 Windows 反编译 Linux 二进制文件 so 谢谢 你可以试试回旋镖 http boomerang sourceforge net 您需要首先从源代码构建它 因为提供的二进制文件不涵盖这种情况 如果您绝对拒绝编译任何内容 请
  • 将 React 应用程序作为后台进程运行

    我对部署前端代码完全陌生 因此提出了这个问题 我有一个 React 应用程序 需要作为后台进程运行 但是我对如何执行此操作有点困惑 我运行一个 npm 脚本 npm run build 在服务器上构建 缩小和服务项目 构建过程的相关代码是这
  • 如何在 Linux 上的 php 中启用 --enable-soap?

    这就是问题所在 我在 Apache 上安装了 PHP 5 2 9 但无法升级 PHP 有没有办法在 PHP 5 2 9 中启用 SOAP PHP 手册中说 要启用 SOAP 支持 请使用 enable soap 配置 PHP 这根本没有帮助
  • 为什么每次运行应用程序时都必须使用导出来定义 LD_LIBRARY_PATH?

    我有一些使用一些共享库的代码 gcc 上的 c 代码 编译时 我必须使用 I 和 L 显式定义包含目录和库目录 因为它们不在标准位置 当我尝试运行代码时 出现以下错误 sync test sync test error while load
  • BASH:[ ](测试)行为不一致

    在我的狂欢中test有态度以身份退出0 test n echo true echo false gt true while test n echo true echo false gt false 这意味着当它根本没有收到任何参数时 它假设
  • (Linux) 如何在没有显示环境的情况下运行gtk程序? Gtk-警告 **:无法打开显示:

    我有一个必须在 GTK gui 环境中运行的程序 我只能使用ssh 该程序将在服务器 centos 6 上运行并安装 gnome X 显示 不需要看GUI 但运行完成后 我就能得到答案 VNC 和远程屏幕已禁用 当我在 ssh 中启动程序时

随机推荐

  • 牛客网 之 数列还原(数列的全排列算法)

    题目描述 牛牛的作业薄上有一个长度为 n 的排列 A 这个排列包含了从1到n的n个数 但是因为一些原因 其中有一些位置 不超过 10 个 看不清了 但是牛牛记得这个数列顺序对的数量是 k 顺序对是指满足 i lt j 且 A i lt A
  • 基于yolov5的物流托盘实时检测方法研究

    摘要 传统物流作业主要依靠人工操作叉车对托盘进行搬运 自动化程度低 工厂实际环境复杂多样 导致现有的托盘检测算法的模型复杂 耗时较长 无法同时达到准确性和实时性要求 难以实际运用 针对浙江某机械 搬运 设备有限公司下属的电动车工业园实际工厂
  • 基于Web日志挖掘的个性化推荐系统(附源码)

    个性化推荐系统 实现该系统主要是使用的编程语言主要是R 然后配合css在样式上进行一定优化 使用shiny开发的一款web程序 主要实现的核心功能是基于spark的ALS算法的课程个性化推荐系统 首页界面如下图所示 该系统中的所有课程名称
  • 低代码点亮普惠数字化转型之路,助力企业数字化转型实践

    在国家大力提倡下 新一代信息技术持续迭代 企业数字化转型被推到风口 现在步入了信息化时代 尤其是2022年 在十四五的政策规划下更是有利好前景 对于企业来说 低代码开发平台是一种通用的解决方案 成为了企业进行信息化管理的首选 现在 越来越多
  • 鸡啄米VS2010/MFC编程入门教程——学习2关于VS2010/MFC/VC/C++

    2015年5月17日15 21 11 VS2010 MFC编程入门之前言 http www jizhuomi com software 137 html 在大学里 有面向对象程序设计这门课程 主要介绍的是C 基础编程 那时候大家虽然都学习了
  • Freemarker中文指南

    序言 目录 一 什么是FreeMarker 二 阅读指南 三 文档约定 四 联系方式 五 关于本文档 一 什么是FreeeMarker FreeMarker是一个模板引擎 是一个基于模板生成文本的通用工具 任何文件都可以基于html自动产生
  • node调用谷歌翻译Api,实现自动国际化

    原因 项目国际化过程繁琐 每次都需要人工去google翻译 导致工作效率不高 需求 1 减少人工的重复劳动 提高工作效率 2 使用脚本调用谷歌翻译接口自动化翻译 3 free 作为程序员肯定接受不了付费服务 找方法解决限制 前期准备 1 谷
  • Java笔记16——优先级队列(堆)

    目录 概念 基于二叉树的堆 二叉堆 基于动态数组ArrayList实现的最大堆 向堆中添加元素 siftUp 在堆中取出最大值 最大堆 3 heapify 堆化 在Java中比较两个元素的大小关系 基于堆的优先级队列到底如何实现 有啥应用
  • 0x00007FFEBAD050D8 处(位于 first.exe 中)有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x0000000DD73CE

    有些时候会出现这种异常 看了网上的一些解释 说有可能是lib文件添置有问题 另一种是路径用成了 我这里给出一种新的可能 那就是图片格式转换错误 这里已经将文件定义为了灰度图像 但是后面使用cvtColor 函数时又将图片转为灰度图像 导致错
  • visio画扇形

    步骤1 首先 选择文件 选项 打开开发工具 步骤2 添加圆形 步骤3 添加两条线 形成扇形的两条边 步骤4 选中圆和线条 在开发工具菜单栏选择操作 修剪 步骤5 选中线条和右边这段弧形 依次选择开发工具 操作 连接 步骤6 拖动该扇形 填充
  • 用代码生成炫酷的词云图—《你好,李焕英》

    最近比较火的电影 你好 李焕英 莫名戳中了大家的泪点 应用评论中的一句 妈妈永远比想象中的要爱我们 虽然我没哭 但看大家都哭了 说明电影不在于多有深意 而是能引起大家共鸣的电影 才是好电影 完全瞎编的 下面我们就来看一下 你好 李焕英 在豆
  • 盛科交换机配置命令_cisco2960交换机 清除配置的命令

    cisco2960交换机 清除配置的命令 1 计算机通过COM端口连接到交机 如果电脑不带COM 需要使用USB转串口线连接交换机 通过超级终端调试 2 当开关通电时 按住开关前面的 模式 按钮 用手按住交换机 Mode 按钮 注意超级终端
  • Uploads-labs靶场练习记录8、9、10-绕过服务端检测(文件后缀)

    这是第八关 1 提示显示不可以上传所有可解析的后缀 那就用png配合htaccess转换php吧 2 成功 这是第九关 1 修改大小写发现还是不能上传 2 后缀加上 DATA上传 成功 这是第十关 1 尝试修改为filename phpin
  • 程序编译链接过程

    文章目录 前言 一 预编译阶段 二 编译阶段 三 汇编阶段 四 链接阶段 总结 前言 include
  • 【msvcp140.dll怎么下载】msvcp140.dll丢失的解决方法

    msvcp140 dll文件对一些电脑软件 电脑游戏等程序的正常运行起到关键性作用 对于弹出缺少此类文件的弹窗 用户们很多时候也摸不着头脑 程序明明上次都能正常运行 突然就弹出缺少msvcp140 dll文件的提醒窗口 通过小编此次编辑的文
  • 多益研发岗视频面试

    03 13 这是自己的第三场面试 自认为面试得还可以 90 以上的问题都答对了 但一个星期后通知说挂了 还是会觉得困惑与可惜 今后再巩固各个知识点吧 39min 1 自我介绍 2 项目介绍 3 项目中有什么亮点或者遇到什么难点 4 说说数据
  • 用HTML做一個酷炫的照片墻,效果非常酷炫。

    下面給大家看看效果 想不想要代碼呢 上代碼
  • 关于字符串二进制定点数浮点数与int以及NBCD码转换的问题

    关于字符串二进制定点数浮点数与int以及NBCD码转换的问题 代码 将十进制数字字符串转化为二进制补码 32位 public String intToBinary String numStr int num Integer parseInt
  • API-应用程序编程接口

    API 定义 通俗理解 定义 API Application Programming Interface 应用程序接口 是一些预先定义的接口 如函数 HTTP接口 或指软件系统不同组成部分衔接的约定 1 用来提供应用程序与开发人员基于某软件
  • 《迅为开发板i.MX8MM 学习记录》——【MIPI篇】Linux 应用程序显示一张图片

    文章目录 前言 一 准备工作 1 开发环境 2 文件准备 二 伪代码分析 1 读取图片数据到数组 2 打开DRM设备 创建fb 3 填充framebuffer 三 完整代码 1 app h 2 app c 四 编译与运行 1 编译 2 运行