借鉴我的代码给个赞再走呗!,我瞅瞅有几个人借鉴
bmp格式图片里,图像数据存储方式是倒叙式
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BYTE1 __attribute__((packed, aligned(1)))
typedef struct FILEHEADER
{
short bfType; //位图类型
int bfSize; //bmp图像文件的大小
short bfReserved1; //0
short bfReserved2; //0
int bfOffBits; //BMP图像数据的偏移地址 54
} BYTE1 BITMAPFILEHEADER;
typedef struct INFOHEADER
{
unsigned int biSize; //本结构的大小
unsigned int biWidth; //BMP图像的宽度,单位像素
unsigned int biHeight; //BMP图像的高度,单位像素
short biPlanes; //1
short biBitCount; //BMP图像的色深,即一个像素用多少位表示
unsigned int biCompression; //压缩方式,0表示不压缩
unsigned int biSizeImage; //BMP图像数据大小,单位字节
unsigned int biXPelsPerMeter; //水平分辨率,单位像素 (还没搞清楚是啥)
unsigned int biYPelsPerMeter; //垂直分辨率,单位像素 (还没搞清楚是啥)
unsigned int biClrUsed; //BMP图像使用的颜色,0表示使用全部颜色
unsigned int biClrImportant; //重要的颜色数,此值为0时所有颜色都重要,
} BITMAPINFOHEADER;
void FuncPrintBmpinfo(BITMAPFILEHEADER bmpFileHeader, BITMAPINFOHEADER bmpInfo)
{
#if 1
printf("bmpFileHeader.bfType %x\n",bmpFileHeader.bfType );
printf("bmpFileHeader.bfSize %d \n",bmpFileHeader.bfSize );
printf("bmpFileHeader.bfReserved1 %d\n",bmpFileHeader.bfReserved1 );
printf("bmpFileHeader.bfReserved2 %d\n",bmpFileHeader.bfReserved2 );
printf("bmpFileHeader.bfOffBits %d\n\n",bmpFileHeader.bfOffBits );
printf("bmpInfo.biSize %d\n", bmpInfo.biSize);
printf("bmpInfo.biWidth %d\n",bmpInfo.biWidth);
printf("bmpInfo.biHeight %d\n",bmpInfo.biHeight );
printf("bmpInfo.biPlanes %d\n",bmpInfo.biPlanes );
printf("bmpInfo.biBitCount %d\n",bmpInfo.biBitCount );
printf("bmpInfo.biCompression %d\n",bmpInfo.biCompression );
printf("bmpInfo.biSizeImage %d\n",bmpInfo.biSizeImage );
printf("bmpInfo.biXPelsPerMeter %d\n",bmpInfo.biXPelsPerMeter );
printf("bmpInfo.biYPelsPerMeter %d\n",bmpInfo.biYPelsPerMeter );
printf("bmpInfo.biClrUsed %d\n",bmpInfo.biClrUsed );
printf("bmpInfo.biClrImportant %d\n\n",bmpInfo.biClrImportant );
#endif
}
/* 顺时针旋转90°*/
int FuncRotateClockwise(const char * bmpname)
{
int ret = 0;
int s32Ret = 0;
FILE * fp = NULL;
char *gPBmpBuf = NULL;
char *arr = NULL;
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfo;
int b = 0;
int w = 0;
int h = 0;
int stride = 0;
int stridew = 0; //跨度应该4对其,原跨度
int strideh = 0; //跨度应该4对其,旋转后的跨度
int sizesrc = 0;
int sizetar = 0;
do
{
if(NULL == bmpname)
{
s32Ret = -1;
break;
}
fp = fopen(bmpname, "rb+");
if(NULL == fp)
{
s32Ret = -2;
break;
}
memset(&bmpFileHeader, 0, sizeof(bmpFileHeader));
memset(&bmpInfo, 0, sizeof(bmpInfo));
ret = fread(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
if(ret <= 0)
{
s32Ret = -3;
break;
}
ret = fread(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp);
if(ret <= 0)
{
s32Ret = -4;
break;
}
FuncPrintBmpinfo(bmpFileHeader, bmpInfo);
b = bmpInfo.biBitCount / 8;
w = bmpInfo.biWidth;
h = bmpInfo.biHeight;
if(b != 3)
{
s32Ret = -5;
break;
}
stride = w*3;
stridew = (w*3+3)/4*4; //跨度应该4对其,原跨度
strideh = (h*3+3)/4*4; //跨度应该4对其,旋转后的跨度
sizesrc = stridew * h;
sizetar = strideh * w;
gPBmpBuf = (char *)malloc(sizesrc);
if(NULL == gPBmpBuf)
{
s32Ret = -6;
break;
}
arr = (char *)malloc(sizetar);
if(NULL == arr)
{
s32Ret = -7;
break;
}
ret = fread(gPBmpBuf, 1, sizesrc, fp);
if(ret <= 0)
{
s32Ret = -8;
break;
}
for(int j=0; j<h; j++) //高
{
for(int i=0; i<stride; i=i+3) //宽
{
memcpy(arr+(3*j+(w-1-i/3)*strideh), gPBmpBuf+(i+j*stridew), 3);
}
}
bmpInfo.biWidth = h;
bmpInfo.biHeight = w;
bmpInfo.biSizeImage = sizetar;
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpInfo.biSizeImage;
fseek(fp, 0, SEEK_SET);
fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp);
fwrite(arr, 1, bmpInfo.biSizeImage, fp);
FuncPrintBmpinfo(bmpFileHeader, bmpInfo);
}while(0);
if(NULL != gPBmpBuf)
{
free(gPBmpBuf);
gPBmpBuf = NULL;
}
if(NULL != arr)
{
free(arr);
arr = NULL;
}
if(NULL != fp)
{
fclose(fp);
fp = NULL;
}
return s32Ret;
}
/* 逆时针旋90° */
int FuncRotateAntiClockwise(const char * bmpname)
{
int ret = 0;
int s32Ret = 0;
FILE * fp = NULL;
char *gPBmpBuf = NULL;
char *arr = NULL;
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfo;
int b = 0;
int w = 0;
int h = 0;
int stride = 0;
int stridew = 0;
int strideh = 0;
int sizesrc = 0;
int sizetar = 0;
do
{
if(NULL == bmpname)
{
s32Ret = -1;
break;
}
fp = fopen(bmpname, "rb+");
if(NULL == fp)
{
s32Ret = -2;
break;
}
memset(&bmpFileHeader, 0, sizeof(bmpFileHeader));
memset(&bmpInfo, 0, sizeof(bmpInfo));
ret = fread(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
if(ret <= 0)
{
s32Ret = -3;
break;
}
ret = fread(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp);
if(ret <= 0)
{
s32Ret = -4;
break;
}
FuncPrintBmpinfo(bmpFileHeader, bmpInfo);
b = bmpInfo.biBitCount / 8;
w = bmpInfo.biWidth;
h = bmpInfo.biHeight;
if(b != 3)
{
s32Ret = -5;
break;
}
stride = w*3;
stridew = (w*3+3)/4*4; //跨度应该4对其,原跨度
strideh = (h*3+3)/4*4; //跨度应该4对其,旋转后的跨度
sizesrc = stridew * h;
sizetar = strideh * w;
gPBmpBuf = (char *)malloc(sizesrc);
if(NULL == gPBmpBuf)
{
s32Ret = -6;
break;
}
arr = (char *)malloc(sizetar);
if(NULL == arr)
{
s32Ret = -7;
break;
}
ret = fread(gPBmpBuf, 1, sizesrc, fp);
if(ret <= 0)
{
s32Ret = -8;
break;
}
for(int j=0; j<h; j++) //高
{
for(int i=0; i<stride; i=i+3) //宽
{
memcpy(arr+(3*(h-1-j)+(i/3)*strideh), gPBmpBuf+i+j*stridew, 3);
}
}
bmpInfo.biWidth = h;
bmpInfo.biHeight = w;
bmpInfo.biSizeImage = sizetar;
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpInfo.biSizeImage;
fseek(fp, 0, SEEK_SET);
fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp);
fwrite(arr, 1, bmpInfo.biSizeImage, fp);
FuncPrintBmpinfo(bmpFileHeader, bmpInfo);
}while(0);
if(NULL != gPBmpBuf)
{
free(gPBmpBuf);
gPBmpBuf = NULL;
}
if(NULL != arr)
{
free(arr);
arr = NULL;
}
if(NULL != fp)
{
fclose(fp);
fp = NULL;
}
return s32Ret;
}
int main()
{
FuncRotateAntiClockwise("yes.bmp");
// FuncRotateClockwise("yes.bmp");
}