lgw9527 2017-04-08 11:07 采纳率: 0%
浏览 1671
已结题

求大神帮我改一下代码,关于BMP图像压缩的

分段不正确,也不知道哪里错了
#include "stdafx.h"
#include
#include
#include
#include"windows.h"
#include"WINGDI.h"//图形设备接口
using namespace std;

#define Imax 256
#define header 11//每段像素段标题固定信息所占位数

class Bitmap
{
public:
int m;//像素段数
int bmpwidth;//图像宽度
int bmpheight;//图像高度
int bitcount;//图像一个像素用多少位表示
int linebyte;//每行像素的字节数
unsigned char **theBMP;//先用二维数组读入位图信息
unsigned char *pBMP;//读入图像数据的数组
unsigned char *unpBMP;
char *filemsg;//存位图文件头信息
char *BMPmsg;//存位图信息头信息
int *s, *l, *b;//s[i]:表示从0到i压缩一共占多少存储空间,l[i]:第i个像素段有l[i]个像素点,b[i]:第i个像素段的每个像素点占b[i]个位数
BITMAPFILEHEADER fhead;//位图文件头
BITMAPINFOHEADER head;//位图信息头
RGBQUAD *colorTable;//颜色表指针
int length(int i);//计算整数的二进制长度
void traceback(int n, int *s, int *l);
void output(unsigned char *p,int *s, int *l, int *b);
void store(char *a, int *j, int *left, int bit, int temp);
void ReadBitmap(char *inFile);//读位图文件
void Compress(char *outComFile, unsigned char *p);//压缩

};
//计算整数的二进制长度
int Bitmap::length(int i)
{
int k = 1;
i = i / 2;
if (i > 0)
{
k++;
i = i / 2;
}
return k;
}
void Bitmap::traceback(int n, int s, int *l)
{
if (n <= 0)
return;
traceback(n - l[n], s, l);
s[m++] = n - l[n];//重新为s[]数组赋值,用来存储分段位置
}
void Bitmap::output(unsigned char *p, int *s, int *l, int *b)
{
int max;
int n = bmpheight*bmpwidth;
traceback(n, s, l);
s[m] = n;
for (int i = 1; i <= m; i++)
{
l[i] = l[s[i]];
max = -1;
for (int j = s[i - 1] + 1; j <= s[i]; j++)
{
if (length(p[j]) > max)
max = length(p[j]);
}
b[i] = max;
}
}
void Bitmap::store(char *a, int *j, int *left, int bit, int temp)
{
if (*left <= bit)
{
a[(*j)++] += temp >> (bit - (*left));
a[(*j)] += (temp << (8 + (*left) - bit)) & 0xff;
*left = 8 - (bit - (*left));
}
else
{
a[(*j)] += (temp << (*left - bit)) & 0xff;
*left -= bit;
}
}
void Bitmap::ReadBitmap(char *inFile)
{
ifstream infile(inFile,ios::binary);
if (!infile)
cerr << "open error!" << endl;
infile.read((char
)&fhead,sizeof(BITMAPFILEHEADER));//读入文件头信息,储存在fhead中
infile.read((char*)&head, sizeof(BITMAPINFOHEADER));//读入信息头信息,储存在head中
bmpheight = head.biHeight;
bmpwidth = head.biWidth;
bitcount = head.biBitCount;
linebyte = (bmpwidth * bitcount / 8 + 3) / 4 * 4;//保证每行的像素字节是4的倍数
if (bitcount == 8)
{
colorTable = new RGBQUAD[256];
infile.read((char*)colorTable, 256*sizeof(RGBQUAD));//读调色板信息并存入内存
}
infile.seekg(fhead.bfOffBits+1, ios::beg);//把文件读指针指到图片信息位置
theBMP = new unsigned char*[bmpheight];
for (int i = 0; i < bmpheight; i++)//像素信息存到二维数组里
{
theBMP[i] = new unsigned char[linebyte];
infile.read((char*)theBMP[i], linebyte);
}
pBMP = new unsigned char[linebyte*bmpheight + 1];//申请位图数据所需的空间,读位图数据进内存
int k = 1;
for (int i = 0; i < bmpheight; i++)//将图片数据蛇形读入数组pBMP
{
if (i % 2 == 0)
for (int j = 0; j < linebyte; j++)
pBMP[k++] = theBMP[i][j];
else
for (int j = linebyte - 1; j >= 0; j--)
pBMP[k++] = theBMP[i][j];
}
for (int i = 0; i < bmpheight; i++)
delete[]theBMP[i];
delete[]theBMP;
infile.close();
}
//l[i]:第i个像素段有l[i]个像素点,b[i]:第i个像素段的每个像素点占b[i]个位数
//s[i]:表示从0到i压缩一共占多少存储空间
void Bitmap::Compress(char outComFile ,unsigned char *p)
{
int size = bmpwidth*bmpheight;//图像的像素点数
int left = 8, k = 1, t;//
int bmax;
s = new int[size + 1];
l = new int[size + 1];
b = new int[size + 1];
s[0] = 0;
m = 1;//初始化段数
for (int i = 1; i <= size; i++)
{
b[i] = length(p[i]);
bmax = b[i];
s[i] = s[i - 1] + bmax;
l[i] = 1;
for (int j = 2; j <= i&&j <= Imax; j++)
{
if (bmax < b[i - j + 1])//找到该段每个像素点所占最大的位数
{
bmax = b[i - j + 1];
}
if (s[i] >(s[i - j] + j*bmax))//该段所用的最小储存位数,j是该段的像素点个数
{
s[i] = s[i - j] + j*bmax;
l[i] = j;
}
}
s[i] += header;
}
output(p, s, l, b);
ofstream outfile(outComFile, ios::binary);
if (!outfile)
cerr << "open error!" << endl;
char
compress_msg = new char[size+1];//储存压缩后的图像信息
for (int i = 0; i <= size; i++)
compress_msg[i] = 0;
int j = 0;
for (int i = 1; i <= m; i++)
{
store(compress_msg, &j, &left, 8, l[i] - 1);
store(compress_msg, &j, &left, 3, b[i] - 1);
t = k + l[i];
for (; k < t; k++)
{
store(compress_msg, &j, &left, b[i], p[k]);
}
}
head.biSizeImage = j + 1;
cout << j + 1;
outfile.write((char*)(&fhead), sizeof(BITMAPFILEHEADER));//写入文件头
outfile.write((char*)(&head), sizeof(BITMAPINFOHEADER));//写入信息头
outfile.write((char*)(&colorTable), strlen((char*)&colorTable));//写入调色板信息
outfile.write(compress_msg, j + 1);//写入压缩后的图片信息
outfile.close();
}
int main()
{
Bitmap test;
char *filename="截图.bmp";
char *outcomfile = "myComfile.txt";
test.ReadBitmap(filename);
test.Compress(outcomfile, test.pBMP);
return 0;
}

  • 写回答

1条回答 默认 最新

  • devmiao 2017-04-08 15:21
    关注
    评论

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大