目录
oled尺寸
如何生成用到的图片
图片转字模
1.首先用Img2Lcd转成bmp单色图片
2.然后用PCtoLCD2002把单色图片转字模
oled尺寸
我使用0.96寸oled模块,对应着的分辨率是128*64,对应着宽高像素比128*64。所以不是随意一张图片就能用的,必须用128*64.
如何生成用到的图片
通过视频获取一张图片
ffmpeg -i 1.mp4 -y -f image2 -vframes 1 -s 128x64 output.jpg
-vframes 1 : 设置只提取 1 帧图像 , 也就是 第 2 秒后的 第一帧图像 ;
-s 128x64: 设置输出图片的大小为 128x64像素 ;
通过其他分辨率的图片获取图片
ffmpeg -i QQ.jpg -y -f image2 -s 128x64 output.jpg
最后获取下图:
图片转字模
1.首先用Img2Lcd转成bmp单色图片
2.然后用PCtoLCD2002把单色图片转字模
一、点击文件,打开要用的图片,如下图
二、选择图形模式
三、点击设置按钮,设置如下图,然后点击确定按钮
四、最后点击生成字模,然后保存字模到txt文本文件
五、然后把数据复制到代码里,需要注意分辨率为128*64,表示有128*64个位,那么对应128*8个字节,也就是1024。
const uint8_t image[1024] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,
0x40,0x20,0x20,0x20,0x80,0x10,0x10,0x90,0x90,0x80,0x80,0x80,0x80,0xD0,0xD0,0xD0,
0xF0,0xA0,0xA0,0xA0,0xA0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0x60,0x78,0x6C,0xA2,0xA1,0x31,0x48,0xE4,0xF0,
0xFA,0xFC,0xFF,0x3E,0x1E,0x1F,0x3F,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFD,0xF9,0xF1,0xE1,0x83,0x03,0x07,0x1E,0xFC,0xF8,0xF0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x80,0xC0,0x60,0x90,0x58,0xA8,0x84,
0x74,0x02,0xE2,0x42,0x4F,0x18,0x30,0x20,0x20,0x60,0xB0,0x1F,0x06,0x10,0x3F,0x3F,
0x7F,0xFF,0xFF,0xFE,0xF2,0xF2,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xF0,0x7C,0x3F,0x1F,0x0F,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
0x1E,0x12,0x01,0x11,0x18,0x38,0xC0,0x80,0x00,0x00,0x03,0x0E,0x05,0x07,0x87,0x98,
0xD0,0x60,0x63,0x6C,0x38,0x30,0x31,0x1F,0x30,0x60,0x41,0x81,0x82,0x86,0x80,0x80,
0x80,0x80,0x80,0xC1,0x43,0x7F,0x1F,0x1B,0x1B,0x1B,0x9B,0x9F,0xBF,0xBF,0x2F,0x4F,
0x4F,0x4F,0x8F,0x87,0xF7,0x0B,0x0B,0x07,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x61,0x39,0x18,0x06,0xC6,0xE3,0xF1,0xF1,0xF0,
0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x83,0x87,0x87,0x87,
0x87,0x03,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x03,0x03,
0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0x0C,0x18,0x30,0x60,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xF8,0xF0,0xC0,0xC0,0x80,0x81,0x80,0x80,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x07,
0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0xFC,0xFC,0xFE,0x7E,0xBE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xF8,0xE0,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x3B,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xE0,0xF0,0xF0,0xF0,
0xF8,0xF8,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0xF0,0xC0,0xC0,0xC0,0xC0,0xC1,0xC1,0xC1,
0xE1,0xE3,0xE1,0xF1,0xF1,0xF0,0xF8,0xF8,0x68,0x34,0x1C,0x0E,0x07,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x07,
0x07,0x07,0x0F,0x0F,0x0F,0x1F,0x1F,0x1F,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,0x1F,0x1F,0x1F,0x0F,0x0F,
0x0F,0x07,0x07,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
这里给出一个如何使用字模数据的案例:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include "font.h"
#define OLED_IOC_INIT 123
#define OLED_IOC_SET_POS 124
//为0 表示命令,为1表示数据
#define OLED_CMD 0
#define OLED_DATA 1
static int fd_spidev;
static int dc_pin_num;
unsigned char OLED_DisplayBuf[8][128];
void OLED_DIsp_Set_Pos(int x, int y);
void oled_write_datas(const unsigned char *buf, int len)
{
write(fd_spidev, buf, len);
}
/**********************************************************************
* 函数名称: OLED_DIsp_Clear
* 功能描述: 整个屏幕显示数据清0
* 输入参数:无
* 输出参数: 无
* 返 回 值:
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_Clear(void)
{
unsigned char x, y;
char buf[128];
memset(buf, 0, 128);
for (y = 0; y < 8; y++)
{
OLED_DIsp_Set_Pos(0, y);
oled_write_datas(buf, 128);
}
}
/**********************************************************************
* 函数名称: OLED_DIsp_All
* 功能描述: 整个屏幕显示全部点亮,可以用于检查坏点
* 输入参数:无
* 输出参数:无
* 返 回 值:
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_All(void)
{
unsigned char x, y;
char buf[128];
memset(buf, 0xff, 128);
for (y = 0; y < 8; y++)
{
OLED_DIsp_Set_Pos(0, y);
oled_write_datas(buf, 128);
}
}
//坐标设置
/**********************************************************************
* 函数名称: OLED_DIsp_Set_Pos
* 功能描述:设置要显示的位置
* 输入参数:@ x :要显示的column address
@y :要显示的page address
* 输出参数: 无
* 返 回 值:
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_Set_Pos(int x, int y)
{
ioctl(fd_spidev, OLED_IOC_SET_POS, x | (y << 8));
}
/**********************************************************************
* 函数名称: OLED_DIsp_Char
* 功能描述:在某个位置显示字符 1-9
* 输入参数:@ x :要显示的column address
@y :要显示的page address
@c :要显示的字符的ascii码
* 输出参数: 无
* 返 回 值:
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_Char(int x, int y, unsigned char c)
{
int i = 0;
/* 得到字模 */
const unsigned char *dots = oled_asc2_8x16[c - ' '];
/* 发给OLED */
OLED_DIsp_Set_Pos(x, y);
/* 发出8字节数据 */
//for (i = 0; i < 8; i++)
// oled_write_cmd_data(dots[i], OLED_DATA);
oled_write_datas(&dots[0], 8);
OLED_DIsp_Set_Pos(x, y+1);
/* 发出8字节数据 */
//for (i = 0; i < 8; i++)
//oled_write_cmd_data(dots[i+8], OLED_DATA);
oled_write_datas(&dots[8], 8);
}
/**********************************************************************
* 函数名称: OLED_DIsp_String
* 功能描述: 在指定位置显示字符串
* 输入参数:@ x :要显示的column address
@y :要显示的page address
@str :要显示的字符串
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_String(int x, int y, char *str)
{
unsigned char j=0;
while (str[j])
{
OLED_DIsp_Char(x, y, str[j]);//显示单个字符
x += 8;
if(x > 127)
{
x = 0;
y += 2;
}//移动显示位置
j++;
}
}
void OLED_Clear(void)
{
uint8_t i, j;
for (j = 0; j < 8; j ++) //遍历8页
{
for (i = 0; i < 128; i ++) //遍历128列
{
OLED_DisplayBuf[j][i] = 0x00; //将显存数组数据全部清零
}
}
}
void OLED_DIsp_Image(int X, int Y, int Width, int Height, const unsigned char *Image)
{
int i = 0, j = 0;
int Page, Shift;
/*遍历指定图像涉及的相关页*/
/*(Height - 1) / 8 + 1的目的是Height / 8并向上取整*/
for (j = 0; j < (Height - 1) / 8 + 1; j ++)
{
/*遍历指定图像涉及的相关列*/
for (i = 0; i < Width; i ++)
{
if (X + i >= 0 && X + i <= 127) //超出屏幕的内容不显示
{
/*负数坐标在计算页地址和移位时需要加一个偏移*/
Page = Y / 8;
Shift = Y % 8;
if (Y < 0)
{
Page -= 1;
Shift += 8;
}
if (Page + j >= 0 && Page + j <= 7) //超出屏幕的内容不显示
{
/*显示图像在当前页的内容*/
OLED_DisplayBuf[Page + j][X + i] |= Image[j * Width + i] << (Shift);
}
if (Page + j + 1 >= 0 && Page + j + 1 <= 7) //超出屏幕的内容不显示
{
/*显示图像在下一页的内容*/
OLED_DisplayBuf[Page + j + 1][X + i] |= Image[j * Width + i] >> (8 - Shift);
}
}
}
}
/*遍历每一页*/
for (int j = 0; j < 8; j ++)
{
/*设置光标位置为每一页的第一列*/
//OLED_SetCursor(j, 0);
OLED_DIsp_Set_Pos(0,j);
/*连续写入128个数据,将显存数组的数据写入到OLED硬件*/
//OLED_WriteData(OLED_DisplayBuf[j], 128);
for(int t=0;t<128;t++)
{//显示上半截字符
oled_write_datas(&OLED_DisplayBuf[j][t], 1);
}
}
}
/**********************************************************************
* 函数名称: OLED_DIsp_Test
* 功能描述: 整个屏幕显示测试
* 输入参数:无
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/03/15 V1.0 芯晓 创建
***********************************************************************/
void OLED_DIsp_Test(void)
{
int i;
OLED_DIsp_Image(0,0,128,64,image);
}
/* spi_oled /dev/100ask_oled */
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("Usage: %s /dev/100ask_oled\n", argv[0]);
return -1;
}
fd_spidev = open(argv[1], O_RDWR);
if (fd_spidev < 0) {
printf("open %s err\n", argv[1]);
return -1;
}
ioctl(fd_spidev, OLED_IOC_INIT);
OLED_DIsp_Clear();
OLED_DIsp_Test();
return 0;
}
以上案例代码主要在OLED_DIsp_Image中,把图片数据填充到OLED_DisplayBuf二维数组中,然后调用 oled_write_datas写入oled显示。