哈夫曼编码图像压缩c++实现

时间: 2023-07-16 20:16:17 浏览: 145
DOCX

哈夫曼编码实现图像压缩

哈夫曼编码是一种常用的数据压缩方式,其中图像压缩是哈夫曼编码的一个应用场景。下面是一个简单的C++实现,用于将图像进行哈夫曼编码压缩。 ``` #include <iostream> #include <fstream> #include <queue> #include <map> #include <vector> using namespace std; // 哈夫曼树节点 struct HuffmanNode { int value; // 节点的值 int weight; // 权重 HuffmanNode* left; HuffmanNode* right; // 构造函数 HuffmanNode(int v, int w) : value(v), weight(w), left(nullptr), right(nullptr) {} HuffmanNode(int v, int w, HuffmanNode* l, HuffmanNode* r) : value(v), weight(w), left(l), right(r) {} }; // 优先队列中的比较函数 struct Compare { bool operator() (HuffmanNode* a, HuffmanNode* b) { return a->weight > b->weight; } }; // 构建哈夫曼树 HuffmanNode* BuildHuffmanTree(map<int, int>& freq) { priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare> pq; for (auto iter = freq.begin(); iter != freq.end(); ++iter) { pq.push(new HuffmanNode(iter->first, iter->second)); } while (pq.size() > 1) { HuffmanNode* left = pq.top(); pq.pop(); HuffmanNode* right = pq.top(); pq.pop(); pq.push(new HuffmanNode(-1, left->weight + right->weight, left, right)); } return pq.top(); } // 递归生成哈夫曼编码 void GenerateHuffmanCode(HuffmanNode* root, map<int, string>& huffmanCode, string code) { if (root == nullptr) { return; } if (root->left == nullptr && root->right == nullptr) { huffmanCode[root->value] = code; return; } GenerateHuffmanCode(root->left, huffmanCode, code + "0"); GenerateHuffmanCode(root->right, huffmanCode, code + "1"); } // 哈夫曼编码压缩 void HuffmanCompression(const char* inputFileName, const char* outputFileName) { ifstream inputFile(inputFileName, ios::binary); if (!inputFile.is_open()) { cout << "Failed to open file: " << inputFileName << endl; return; } // 统计每个字节的频率 map<int, int> freq; while (!inputFile.eof()) { char byte; inputFile.read(&byte, 1); freq[byte]++; } inputFile.close(); // 构建哈夫曼树 HuffmanNode* root = BuildHuffmanTree(freq); // 生成哈夫曼编码 map<int, string> huffmanCode; GenerateHuffmanCode(root, huffmanCode, ""); // 写入压缩后的文件 ofstream outputFile(outputFileName, ios::binary); if (!outputFile.is_open()) { cout << "Failed to create file: " << outputFileName << endl; return; } // 写入哈夫曼编码表 int codeTableSize = huffmanCode.size(); outputFile.write(reinterpret_cast<char*>(&codeTableSize), sizeof(codeTableSize)); for (auto iter = huffmanCode.begin(); iter != huffmanCode.end(); ++iter) { int byte = iter->first; int codeLength = iter->second.length(); string code = iter->second; outputFile.write(reinterpret_cast<char*>(&byte), sizeof(byte)); outputFile.write(reinterpret_cast<char*>(&codeLength), sizeof(codeLength)); outputFile.write(code.c_str(), codeLength); } // 写入压缩后的数据 inputFile.open(inputFileName, ios::binary); while (!inputFile.eof()) { char byte; inputFile.read(&byte, 1); if (!inputFile.eof()) { string code = huffmanCode[byte]; for (int i = 0; i < code.length(); ++i) { char bit = code[i]; outputFile.write(&bit, 1); } } } inputFile.close(); outputFile.close(); cout << "Compression completed." << endl; } // 哈夫曼解压缩 void HuffmanDecompression(const char* inputFileName, const char* outputFileName) { ifstream inputFile(inputFileName, ios::binary); if (!inputFile.is_open()) { cout << "Failed to open file: " << inputFileName << endl; return; } // 读取哈夫曼编码表 int codeTableSize; inputFile.read(reinterpret_cast<char*>(&codeTableSize), sizeof(codeTableSize)); map<int, string> huffmanCode; for (int i = 0; i < codeTableSize; ++i) { int byte; int codeLength; inputFile.read(reinterpret_cast<char*>(&byte), sizeof(byte)); inputFile.read(reinterpret_cast<char*>(&codeLength), sizeof(codeLength)); char* code = new char[codeLength + 1]; inputFile.read(code, codeLength); code[codeLength] = '\0'; huffmanCode[byte] = code; delete[] code; } // 解压缩数据 ofstream outputFile(outputFileName, ios::binary); if (!outputFile.is_open()) { cout << "Failed to create file: " << outputFileName << endl; return; } HuffmanNode* root = BuildHuffmanTree(huffmanCode); HuffmanNode* node = root; while (!inputFile.eof()) { char bit; inputFile.read(&bit, 1); if (!inputFile.eof()) { if (bit == '0') { node = node->left; } else { node = node->right; } if (node->left == nullptr && node->right == nullptr) { outputFile.write(reinterpret_cast<char*>(&node->value), sizeof(node->value)); node = root; } } } inputFile.close(); outputFile.close(); cout << "Decompression completed." << endl; } int main() { const char* inputFileName = "input.bmp"; const char* compressedFileName = "compressed.bin"; const char* outputFileName = "output.bmp"; HuffmanCompression(inputFileName, compressedFileName); HuffmanDecompression(compressedFileName, outputFileName); return 0; } ``` 这个实现中,使用map记录每个字节的频率,然后使用优先队列(堆)来构建哈夫曼树。最后递归生成每个字节的哈夫曼编码,并将编码表和压缩后的数据写入文件中。解压缩时,首先读取哈夫曼编码表,然后逐位读取压缩后的数据,利用哈夫曼树进行解码,并将解码后的字节写入文件中。
阅读全文

相关推荐

zip
【项目介绍】 课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip 课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip 课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip 课程大作业基于哈夫曼编码和动态规划的图像压缩算法c++实现源码(含详细注释+测试样例).zip 【备注】 1.项目代码均经过功能验证,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈!

最新推荐

recommend-type

哈夫曼编码压缩解压缩程序(CPP写的)

本文将深入探讨哈夫曼编码的原理,并通过一个使用C++编写的哈夫曼编码压缩解压缩程序,来阐述其具体实现过程。 哈夫曼编码的基本思想是将出现频率高的字符赋予较短的编码,而频率低的字符赋予较长的编码,这样在...
recommend-type

哈夫曼编码的研究与实现

哈夫曼编码在实际应用中,如文件压缩工具WinRAR、gzip,以及图像压缩标准JPEG中都有所体现。尽管现代压缩算法往往结合了其他技术,如算术编码、LZ77等,哈夫曼编码仍然因其简单高效而被广泛使用。 在C++编程环境下...
recommend-type

用哈夫曼编码统计一段英文中字母的频率

本节课程设计旨在帮助学生掌握哈夫曼编码的基本原理和应用,并且能够使用C++语言来实现哈夫曼编码的统计和编码功能。通过本节课程设计,学生将获得丰富的编程经验和实践能力,并且能够更好地理解哈夫曼编码的原理和...
recommend-type

哈夫曼编/译码器(C++)

在实际应用中,哈夫曼编码常用于文本压缩、图像压缩等领域,能够显著提高数据传输和存储的效率。在编写程序时,注意文件的读写操作,确保正确处理可能出现的错误,如文件无法打开等,以增强程序的健壮性。
recommend-type

数据结构 课程设计 哈夫曼树“编码、译码”器

数据结构课程设计中,哈夫曼树是一种重要的数据结构,主要应用于编码和译码操作。...哈夫曼树的编码和译码机制在数据压缩、文本传输等领域有广泛应用,如在JPEG图像压缩和ZIP文件格式中都有所体现。
recommend-type

平尾装配工作平台运输支撑系统设计与应用

资源摘要信息:"该压缩包文件名为‘行业分类-设备装置-用于平尾装配工作平台的运输支撑系统.zip’,虽然没有提供具体的标签信息,但通过文件标题可以推断出其内容涉及的是航空或者相关重工业领域内的设备装置。从标题来看,该文件集中讲述的是有关平尾装配工作平台的运输支撑系统,这是一种专门用于支撑和运输飞机平尾装配的特殊设备。 平尾,即水平尾翼,是飞机尾部的一个关键部件,它对于飞机的稳定性和控制性起到至关重要的作用。平尾的装配工作通常需要在一个特定的平台上进行,这个平台不仅要保证装配过程中平尾的稳定,还需要适应平尾的搬运和运输。因此,设计出一个合适的运输支撑系统对于提高装配效率和保障装配质量至关重要。 从‘用于平尾装配工作平台的运输支撑系统.pdf’这一文件名称可以推断,该PDF文档应该是详细介绍这种支撑系统的构造、工作原理、使用方法以及其在平尾装配工作中的应用。文档可能包括以下内容: 1. 支撑系统的设计理念:介绍支撑系统设计的基本出发点,如便于操作、稳定性高、强度大、适应性强等。可能涉及的工程学原理、材料学选择和整体结构布局等内容。 2. 结构组件介绍:详细介绍支撑系统的各个组成部分,包括支撑框架、稳定装置、传动机构、导向装置、固定装置等。对于每一个部件的功能、材料构成、制造工艺、耐腐蚀性以及与其他部件的连接方式等都会有详细的描述。 3. 工作原理和操作流程:解释运输支撑系统是如何在装配过程中起到支撑作用的,包括如何调整支撑点以适应不同重量和尺寸的平尾,以及如何进行运输和对接。操作流程部分可能会包含操作步骤、安全措施、维护保养等。 4. 应用案例分析:可能包含实际操作中遇到的问题和解决方案,或是对不同机型平尾装配过程的支撑系统应用案例的详细描述,以此展示系统的实用性和适应性。 5. 技术参数和性能指标:列出支撑系统的具体技术参数,如载重能力、尺寸规格、工作范围、可调节范围、耐用性和可靠性指标等,以供参考和评估。 6. 安全和维护指南:对于支撑系统的使用安全提供指导,包括操作安全、应急处理、日常维护、定期检查和故障排除等内容。 该支撑系统作为专门针对平尾装配而设计的设备,对于飞机制造企业来说,掌握其详细信息是提高生产效率和保障产品质量的重要一环。同时,这种支撑系统的设计和应用也体现了现代工业在专用设备制造方面追求高效、安全和精确的趋势。"
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB遗传算法探索:寻找随机性与确定性的平衡艺术

![MATLAB多种群遗传算法优化](https://img-blog.csdnimg.cn/39452a76c45b4193b4d88d1be16b01f1.png) # 1. 遗传算法的基本概念与起源 遗传算法(Genetic Algorithm, GA)是一种模拟自然选择和遗传学机制的搜索优化算法。起源于20世纪60年代末至70年代初,由John Holland及其学生和同事们在研究自适应系统时首次提出,其理论基础受到生物进化论的启发。遗传算法通过编码一个潜在解决方案的“基因”,构造初始种群,并通过选择、交叉(杂交)和变异等操作模拟生物进化过程,以迭代的方式不断优化和筛选出最适应环境的
recommend-type

如何在S7-200 SMART PLC中使用MB_Client指令实现Modbus TCP通信?请详细解释从连接建立到数据交换的完整步骤。

为了有效地掌握S7-200 SMART PLC中的MB_Client指令,以便实现Modbus TCP通信,建议参考《S7-200 SMART Modbus TCP教程:MB_Client指令与功能码详解》。本教程将引导您了解从连接建立到数据交换的整个过程,并详细解释每个步骤中的关键点。 参考资源链接:[S7-200 SMART Modbus TCP教程:MB_Client指令与功能码详解](https://wenku.csdn.net/doc/119yes2jcm?spm=1055.2569.3001.10343) 首先,确保您的S7-200 SMART CPU支持开放式用户通
recommend-type

MAX-MIN Ant System:用MATLAB解决旅行商问题

资源摘要信息:"Solve TSP by MMAS: Using MAX-MIN Ant System to solve Traveling Salesman Problem - matlab开发" 本资源为解决经典的旅行商问题(Traveling Salesman Problem, TSP)提供了一种基于蚁群算法(Ant Colony Optimization, ACO)的MAX-MIN蚁群系统(MAX-MIN Ant System, MMAS)的Matlab实现。旅行商问题是一个典型的优化问题,要求找到一条最短的路径,让旅行商访问每一个城市一次并返回起点。这个问题属于NP-hard问题,随着城市数量的增加,寻找最优解的难度急剧增加。 MAX-MIN Ant System是一种改进的蚁群优化算法,它在基本的蚁群算法的基础上,对信息素的更新规则进行了改进,以期避免过早收敛和局部最优的问题。MMAS算法通过限制信息素的上下界来确保算法的探索能力和避免过早收敛,它在某些情况下比经典的蚁群系统(Ant System, AS)和带有局部搜索的蚁群系统(Ant Colony System, ACS)更为有效。 在本Matlab实现中,用户可以通过调用ACO函数并传入一个TSP问题文件(例如"filename.tsp")来运行MMAS算法。该问题文件可以是任意的对称或非对称TSP实例,用户可以从特定的网站下载多种标准TSP问题实例,以供测试和研究使用。 使用此资源的用户需要注意,虽然该Matlab代码可以免费用于个人学习和研究目的,但若要用于商业用途,则需要联系作者获取相应的许可。作者的电子邮件地址为***。 此外,压缩包文件名为"MAX-MIN%20Ant%20System.zip",该压缩包包含Matlab代码文件和可能的示例数据文件。用户在使用之前需要将压缩包解压,并将文件放置在Matlab的适当工作目录中。 为了更好地理解和应用该资源,用户应当对蚁群优化算法有初步了解,尤其是对MAX-MIN蚁群系统的基本原理和运行机制有所掌握。此外,熟悉Matlab编程环境和拥有一定的编程经验将有助于用户根据个人需求修改和扩展算法。 在实际应用中,用户可以根据问题规模调整MMAS算法的参数,如蚂蚁数量、信息素蒸发率、信息素增量等,以获得最优的求解效果。此外,也可以结合其他启发式或元启发式算法,如遗传算法、模拟退火等,来进一步提高算法的性能。 总之,本资源为TSP问题的求解提供了一种有效的算法框架,且Matlab作为编程工具的易用性和强大的计算能力,使得该资源成为算法研究人员和工程技术人员的有力工具。通过本资源的应用,用户将能够深入探索并实现蚁群优化算法在实际问题中的应用,为解决复杂的优化问题提供一种新的思路和方法。