目录
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 1static 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显示。