索引图像所占空间小
拿一张尺寸为 (w=1440, h=665) 的彩色照片来说,如下图。一个像素点由 RGB 三个通道的数据表示,灰度级分辨率为 256 ,即 8 个 bit (28=256) 可以存储一个灰度的像素,那么存储一张彩色图像就需要 w×h×3×8(bit) 的空间。存储下面这张彩色图像就需要 1440×665×3×8(bit) = 22,982,400(bit) = 2,872,800(B) ≈ 2,805.47(KB) ≈ 2.74(MB) 的空间。
而通过索引图像的方式存储图片数据,则由原图本身含有的 RGB 颜色组合数量决定,需要的存储空间大小为颜料板中 RGB 颜色组合对加上像素的颜色索引。例如本图像拥有的 RGB 组合对有 30615 对,需要的索引数量为 w×h=1440×665 个,索引值用 8bit 表示即可,则所需存储空间大小为 30615×3×8(bit)+1440×665×8(bit) = 7,660,800(bit) = 957,600(B) ≈ 935.16(KB) ≈ 0.91(MB)。
可以看到,使用索引方式存储图像所占空间大小是原来的 33% ,且为无损压缩,压缩效果很好。

1 #include <stdio.h> 2 #include <math.h> 3 #include "graphics.h" 4 5 int main() { 6 int w=1440, h=665, i, j; 7 8 initgraph(w, h, 0); 9 setcaption("统计颜料板RGB颜色组合对数目"); 10 11 // 存储原图像素值的动态数组 12 short *r = (short *)malloc(w*h*sizeof(short)); 13 short *g = (short *)malloc(w*h*sizeof(short)); 14 short *b = (short *)malloc(w*h*sizeof(short)); 15 16 17 color_t color; 18 PIMAGE pimg = newimage(); 19 getimage(pimg, "image.jpg", w, h); 20 // 获取图像数据 21 for(i=0; i<w; i++) { 22 for(j=0; j<h; j++) { 23 color = getpixel(i, j, pimg); 24 *(r+h*i+j) = EGEGET_R(color); 25 *(g+h*i+j) = EGEGET_G(color); 26 *(b+h*i+j) = EGEGET_B(color); 27 } 28 } 29 30 // 颜料板 31 short idx=0, tr, tg, tb; 32 short *mapR = (short *)malloc(60000*sizeof(short)); 33 short *mapG = (short *)malloc(60000*sizeof(short)); 34 short *mapB = (short *)malloc(60000*sizeof(short)); 35 short *pxls = (short *)malloc(w*h*sizeof(short)); 36 37 bool flag; 38 printf("calculate...\n"); 39 for(i=0; i<w*h; i++) { 40 tr = *(r+i); 41 tg = *(g+i); 42 tb = *(b+i); 43 // 打印每一个像素点 44 color = EGERGB(tr, tg, tb); 45 putpixel(i/h, i%h, color); 46 47 flag = true; 48 for(j=0; j<idx; j++) { 49 // 在颜料板中找到了颜色 50 if( *(mapR+j)==tr && *(mapG+j)==tg && *(mapB+j)==tb ) { 51 *(pxls+i) = j; 52 flag = false; 53 } 54 } 55 // 在颜料板中没找到颜色 56 if(flag) { 57 // 将该颜色添加进颜料板 58 *(mapR+idx) = tr; 59 *(mapG+idx) = tg; 60 *(mapB+idx) = tb; 61 *(pxls+i) = idx; 62 idx++; 63 } 64 } 65 66 printf("map size: %d\n", idx); 67 68 // 清屏并等待一个键入信息 69 cleardevice(); 70 getch(); 71 // 根据索引图像的方式打印图片 72 for(i=0; i<w*h; i++) { 73 tr = *(mapR+*(pxls+i)); 74 tg = *(mapG+*(pxls+i)); 75 tb = *(mapB+*(pxls+i)); 76 color = EGERGB(tr, tg, tb); 77 putpixel(i/h, i%h, color); 78 } 79 80 81 getch(); 82 closegraph(); 83 return 0; 84 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律