索引图像所占空间小

拿一张尺寸为 (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 }
统计颜料板RGB颜色组合对数目
复制代码

 

posted @   HanselHuang  阅读(270)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示