以下是原创的C++代码,可在VC6.0及以上版本测试,相关头文件若缺失请在百度或谷歌下载。
#include <stdio.h>
#include "BmpRot.h"
#include "stdlib.h"
#include "math.h"
#include <iostream>
#include <cmath>
//#include "stdafx.h"
#define pi 3.14159//圆周率宏定义
#define LENGTH_NAME_BMP 30//bmp图片文件名的最大长度
#define num 8
float s[8][8];
float t[8][8];
int n=1,u,v,cv,cu;
using namespace std;
//变量定义
BITMAPFILEHEADER strHead;
RGBQUAD strPla[256];//256色调色板
BITMAPINFOHEADER strInfo;
//显示位图文件头信息
void showBmpHead(BITMAPFILEHEADER pBmpHead){
cout<<"位图文件头:"<<endl;
cout<<"文件大小:"<<pBmpHead.bfSize<<endl;
cout<<"保留字_1:"<<pBmpHead.bfReserved1<<endl;
cout<<"保留字_2:"<<pBmpHead.bfReserved2<<endl;
cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;
}
void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){
cout<<"位图信息头:"<<endl;
cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;
cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;
cout<<"位图高:"<<pBmpInforHead.biHeight<<endl;
cout<<"biPlanes平面数:"<<pBmpInforHead.biPlanes<<endl;
cout<<"biBitCount采用颜色位数:"<<pBmpInforHead.biBitCount<<endl;
cout<<"压缩方式:"<<pBmpInforHead.biCompression<<endl;
cout<<"biSizeImage实际位图数据占用的字节数:"<<pBmpInforHead.biSizeImage<<endl;
cout<<"X方向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;
cout<<"Y方向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;
cout<<"使用的颜色数:"<<pBmpInforHead.biClrUsed<<endl;
cout<<"重要颜色数:"<<pBmpInforHead.biClrImportant<<endl;
}
void dct(float data[num][num],float output[num][num])
{
double cu,cv;
short u=0;
short v=0;
short i=0;
short j=0;
for(u = 0;u < num;u++)
{
for(v = 0;v < num;v++)
{
if(u==0)
cu = sqrt(1.0/2.0);
else
cu = 1;
if(v==0)
cv = sqrt(1.0/2.0);
else
cv = 1;
double tmp=0.0;
for(i = 0;i < num;i++)
{
for(j = 0;j < num;j++)
{
tmp+= (data[i][j])
* cos( (2*i+1) * u * pi / (2.0*num) )
* cos( (2*j+1) * v * pi / (2.0*num) );
}
}
output[u][v]= ( cu * cv /4.0) * tmp;
if(output[u][v]<10 && output[u][v]>-10 )
{output[u][v]=0;}
}
}
}
void idct(float input[num][num],float output[num][num])
{
short i,j,u,v;
double cu,cv;
for(i = 0;i < num;i++)
{
for(j = 0;j < num;j++)
{
double tmp=0.0;
for(u = 0;u < num;u++)
{
for(v = 0;v < num;v++)
{
if(u==0)
cu = sqrt(1.0/2.0);
else
cu = 1;
if(v==0)
cv = sqrt(1.0/2.0);
else
cv = 1;
tmp+= (cu*cv/4.0) * (input[u][v])
* cos( (2*i+1) * u * pi / (2.0*num))
* cos( (2*j+1) * v * pi / (2.0*num));
}
}
output[i][j]=tmp;
}
}
}
int main(){
char strFile[LENGTH_NAME_BMP];//bmp文件名
IMAGEDATA *imagedata = NULL;//动态分配存储原图片的像素信息的二维数组
IMAGEDATA *imagedataRot = NULL;//动态分配存储旋转后的图片的像素信息的二维数组
IMAGEDATA *imagedataRot1 = NULL;
IMAGEDATA *imagedataRot2 = NULL;
int width,height,temp;//图片的宽度和高度
cout<<"请输入所要读取的文件名:"<<endl;
cin>>strFile;
FILE *fpi,*fpw;
fpi=fopen(strFile,"rb");
if(fpi != NULL){
//先读取文件类型
WORD bfType;
fread(&bfType,1,sizeof(WORD),fpi);
if(0x4d42!=bfType)
{
cout<<"the file is not a bmp file!"<<endl;
return NULL;
}
//读取bmp文件的文件头和信息头
fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);
//showBmpHead(strHead);//显示文件头
fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);
//showBmpInforHead(strInfo);//显示文件信息头
//读取调色板
for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++)
{
fread((char *)&(strPla[nCounti].rgbBlue),1,sizeof(BYTE),fpi);
fread((char *)&(strPla[nCounti].rgbGreen),1,sizeof(BYTE),fpi);
fread((char *)&(strPla[nCounti].rgbRed),1,sizeof(BYTE),fpi);
fread((char *)&(strPla[nCounti].rgbReserved),1,sizeof(BYTE),fpi);
}
width = strInfo.biWidth;
height = strInfo.biHeight;
//图像每一行的字节数必须是4的整数倍
width = (width * sizeof(IMAGEDATA) + 3) / 4 * 4;
//imagedata = (IMAGEDATA*)malloc(width * height * sizeof(IMAGEDATA));
imagedata = (IMAGEDATA*)malloc(width * height);
imagedataRot = (IMAGEDATA*)malloc( width * height * sizeof(IMAGEDATA));
imagedataRot1 = (IMAGEDATA*)malloc(width * height);
imagedataRot2 = (IMAGEDATA*)malloc(width * height);
//初始化原始图片的像素数组
for(int i = 0;i < height;++i)
{
for(int j = 0;j < width;++j)
{
(*(imagedata + i * width + j)).blue = 0;
//(*(imagedata + i * width + j)).green = 0;
//(*(imagedata + i * width + j)).red = 0;
}
}
//初始化旋转后图片的像素数组
for( i = 0;i < height;++i)
{
for(int j = 0;j < width;++j)
{
(*(imagedataRot + i * width + j)).blue = 0;
//(*(imagedataRot + i * width + j)).green = 0;
//(*(imagedataRot + i * width + j)).red = 0;
}
}
//fseek(fpi,54,SEEK_SET);
//读出图片的像素数据
fread(imagedata,sizeof(struct tagIMAGEDATA) * width,height,fpi);
fclose(fpi);
}
else
{
cout<<"file open error!"<<endl;
return NULL;
}
int i,j,x,y;
float a[8][8]={0.0};
for(int m = 0;m < 64;m++)
{
for(int n = 0;n < 64;n++)
{
for(i = 0;i < 8;i++)
{ for(j = 0;j < 8;j++)
{
a[i][j]=(float)(*(imagedata + (m*8+i) * width + (n*8+j))).blue;
}
}
dct(a,s);
for(x = 0;x < 8;x++)
{
for(y = 0;y < 8;y++)
{
if( x+y >=4 )
s[x][y]=0;
}
}
idct(s,t);
for(i = 0;i < 8;i++)
{
for(j = 0;j < 8;j++)
{
(*(imagedataRot + (m*8+i )* width + n*8+j)).blue=(unsigned char)t[i][j];
}
}
}
}
//保存bmp图片
if((fpw=fopen("b.bmp","wb"))==NULL)
{
cout<<"create the bmp file error!"<<endl;
return NULL;
}
WORD bfType_w=0x4d42;
fwrite(&bfType_w,1,sizeof(WORD),fpw);
//fpw +=2;
fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpw);
strInfo.biWidth = width;
strInfo.biHeight = height;
fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpw);
for(unsigned int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++)
{
fwrite(&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpw);
fwrite(&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpw);
fwrite(&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpw);
fwrite(&strPla[nCounti].rgbReserved,1,sizeof(BYTE),fpw);
}
//保存像素数据
for(i =0;i < height;++i)
{
for(int j = 0;j < width;++j)
{
fwrite( &((*(imagedataRot + i *width + j)).blue),1,sizeof(BYTE),fpw);
//fwrite( &((*(imagedataRot + i * width + j)).green),1,sizeof(BYTE),fpw);
//fwrite( &((*(imagedataRot + i * width + j)).red),1,sizeof(BYTE),fpw);
}
}
fclose(fpw);
//释放内存
delete[] imagedata;
delete[] imagedataRot;
}
Matlab版本会在后面更新,敬请期待!Matlab效果如下: