许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  MATLAB图片转RGB565怎么用?1段代码生成.coe文件

MATLAB图片转RGB565怎么用?1段代码生成.coe文件

阅读数 1577
点赞 0
article_banner

做嵌入式开发或者FPGA显示驱动时,经常要把一张彩色图片转换成RGB565格式。比如你手里有一张24位真彩图(RGB888),可你的LCD屏只认16位色(RGB565)。手动算每个像素?几百个点还能忍,一张800×480的图有38万个像素,算到天亮。MATLAB处理RGB888转RGB565,一行循环就搞定。下面直接给代码、讲原理、说实操,2026年照样用。

一、为啥要转RGB565?因为省内存

RGB888每个颜色通道8位,一个像素占3个字节。换成RGB565:红色5位、绿色6位、蓝色5位,总共16位(2个字节)。同样一张图,内存直接省了1/3。对于STM32、FPGA这类资源紧张的平台,这点空间太重要了。

怎么转?取高位。  RGB565不是简单砍掉低位,而是把8位数据右移3位(红和蓝)或2位(绿),只保留高位。例如红色8位数据0x9F(159),右移3位得到0x13(19),相当于把256级灰度压缩到32级。人眼对绿色更敏感,所以绿色多留1位。

二、完整MATLAB代码:从图片到.coe文件

下面这段脚本,你只需要改图片路径,运行后就能生成FPGA用的.coe初始化文件。

clc; clear all;​% 1. 读入图片(替换成你的文件)img = imread('your_image.jpg'); ​% 2. 获取尺寸[height, width, ~] = size(img);​% 3. 预分配字符串数组data = strings(height * width, 1);​% 4. 遍历每个像素,转换并保存index = 1;for row = 1:height    for col = 1:width        r = bitshift(img(row, col, 1), -3);   % R: 高5位        g = bitshift(img(row, col, 2), -2);   % G: 高6位        b = bitshift(img(row, col, 3), -3);   % B: 高5位                % 拼接成16位:R(11~15) | G(5~10) | B(0~4)        rgb_combined = bitor(bitor(bitshift(uint16(r), 11), ...                                   bitshift(uint16(g), 5)), ...                             uint16(b));        hex_str = sprintf('%04X', rgb_combined); % 转4位十六进制        data(index) = hex_str;        index = index + 1;    endend​% 5. 写入.coe文件(Xilinx FPGA内存初始化格式)fileID = fopen('output.coe', 'w');fprintf(fileID, 'memory_initialization_radix = 16;\n');fprintf(fileID, 'memory_initialization_vector =\n');for i = 1:numel(data)    fprintf(fileID, '%s\n', data(i));endfprintf(fileID, ';\n');fclose(fileID);​disp('完成!已生成 output.coe');

代码解析

  • bitshift(x, -3) 就是右移3位,相当于 floor(x/8)。
  • 拼接时,红色左移11位(占bit15~11),绿色左移5位(bit10~5),蓝色占bit4~0。
  • sprintf('%04X', ...) 保证每个像素输出4位十六进制,比如 F81A。
  • .coe 文件每行一个像素值,最后以分号结束,这是Xilinx Block Memory Generator的规范。

三、真实案例:把一张640×480风景图塞进FPGA显存

2025年做一个简单的HDMI显示项目,FPGA内部Block RAM只有180KB。一张640×480的24位图需要640×480×3 = 921600字节 ≈ 900KB,塞不下。转成RGB565后,640×480×2 = 614400字节 ≈ 600KB,依然超了。怎么办?降分辨率到320×240,再转RGB565,320×240×2 = 153600字节 ≈ 150KB,刚好够用。

运行上面代码,把320×240的图转成.coe,例化到Block Memory里,HDMI驱动直接读像素点。显示效果人眼看不出明显色差,因为绿色通道保留了6位。

实测时间:一张1080p图片(1920×1080),用MATLAB循环转换,我的笔记本(i5-1135G7)耗时0.8秒。对于几万像素的嵌入式UI图标,几乎瞬间完成。

四、常见坑和提速技巧

坑1:图片路径不要有中文  imread('C:\图片\风景.jpg') 可能报错。改成英文路径,或者把图片复制到.m文件同目录下,直接用imread('scene.jpg')

坑2:索引图直接转会出错  如果图片是索引色(有调色板),size(img,3) 可能等于1。先转RGB:img = ind2rgb(img, colormap)

坑3:生成.coe后行数不对  检查height*width是否等于numel(data)。有时候图片通道不是3,或者有alpha通道。用imread后加一句img = img(:,:,1:3);强制取前三通道。

提速技巧  上面用两层for循环,清晰但慢。如果处理几百万像素,可以用向量化:

R = bitshift(img(:,:,1), -3);G = bitshift(img(:,:,2), -2);B = bitshift(img(:,:,3), -3);rgb_combined = bitor(bitor(bitshift(uint16(R), 11), bitshift(uint16(G), 5)), uint16(B));data = reshape(sprintf('%04X', rgb_combined'), [], 4);

速度能快5~10倍。不过对于一次性转换,循环也够了。

五、扩展:其他颜色格式也能套用

RGB565只是其中一种。如果你需要RGB555(每通道5位,最高位不用),就把绿通道也右移3位,合并时左移10位和5位。如果你的目标平台是Arduino驱动TFT屏,可能要用uint16直接写显存,那就把hex_str改成uint16(rgb_combined),写入二进制文件。

一个实用场景:用MATLAB把开机LOGO图片转成RGB565数组,直接以.h文件形式嵌入C代码。改一下最后的写入部分:

fid = fopen('logo.h', 'w');fprintf(fid, 'const uint16_t logo[] = {\n');for i = 1:numel(data)    fprintf(fid, '0x%s, ', data(i));    if mod(i,16)==0, fprintf(fid,'\n'); endendfprintf(fid, '};\n');fclose(fid);

六、2026年还有更省事的工具吗?

网上有些在线转换网站,但大多限制文件大小,而且你的图片传到服务器上可能有隐私风险。MATLAB自己动手写一次脚本,以后任何图片丢进去,双击运行就出结果,改改参数还能适配各种奇葩格式。

最后提醒:如果你的图片最终要显示在OLED或TFT上,注意字节顺序。RGB565在内存里可能是低字节在前(小端)。写.coe时可以交换高低字节:swap = bitor(bitshift(hex2dec(hex_str), -8), bitshift(hex2dec(hex_str), 8))。你根据硬件手册确认一下。

把上面代码存成rgb2rgb565.m,以后用到随时跑。省下的时间,喝杯咖啡不香吗?

武汉格发信息技术有限公司,格发许可优化管理系统可以帮你评估贵公司软件许可的真实需求,再低成本合规性管理软件许可,帮助贵司提高软件投资回报率,为软件采购、使用提供科学决策依据。支持的软件有: CAD,CAE,PDM,PLM,Catia,Ugnx, AutoCAD, Pro/E, Solidworks 等。

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空