BMP文件右旋90度[c语言]

#include 
#include 
#include 

typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned int LONG;

#pragma pack(2)
typedef struct tagBITMAPFILEHEADER
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
} BITMAPFILEHEADER;
#pragma pack()

typedef struct tagBITMAPINFOHEADER{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER;
/* fname- 输入文件名称 foname-输出文件名 */
void cw90(char *fname,char *foname) {
    
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;
    unsigned char palette[8];
    FILE *f = fopen(fname,"rb");
    
    if(f == NULL) {
        printf("Can not find file %s\n",fname);
        return;
    }
    
    fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,f);
    fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,f);
    fread(palette,sizeof(unsigned char),8,f);
    
    unsigned char *data = (unsigned char*)malloc(infoHeader.biSizeImage);
    
    fread(data,sizeof(unsigned char),infoHeader.biSizeImage,f);
    
    FILE *of = fopen(foname,"wb");    
    
    BITMAPFILEHEADER oFileHeader;
    BITMAPINFOHEADER oInfoHeader;
    
    int lineSize = ( infoHeader.biHeight + 31) / 32 * 4;
    int imageSize = lineSize * infoHeader.biWidth;
    
    // 
    oFileHeader.bfType = 19778;
    oFileHeader.bfSize = 62 + imageSize;
    oFileHeader.bfReserved1 = 0;
    oFileHeader.bfReserved2 = 0;
    oFileHeader.bfOffBits = 62;
    // 
    oInfoHeader.biSize = 40;
    oInfoHeader.biWidth = infoHeader.biHeight;
    oInfoHeader.biHeight = infoHeader.biWidth;
    oInfoHeader.biPlanes = 1;
    oInfoHeader.biBitCount = 1;
    oInfoHeader.biCompression = 0;
    oInfoHeader.biSizeImage = imageSize;
    oInfoHeader.biXPelsPerMeter = 0;
    oInfoHeader.biYPelsPerMeter = 0;
    oInfoHeader.biClrUsed = 0;
    oInfoHeader.biClrImportant = 0;
    // 
    
    fwrite( &oFileHeader , sizeof(BITMAPFILEHEADER) , 1 , of );
    fwrite( &oInfoHeader , sizeof(BITMAPINFOHEADER) , 1 , of );
    fwrite( palette , 1 , 8 , of );
    
    
    unsigned char *first = (unsigned char*)malloc(infoHeader.biHeight * oInfoHeader.biHeight);
    unsigned char *second = (unsigned char*)malloc(infoHeader.biHeight * oInfoHeader.biHeight);
    int myline = oInfoHeader.biSizeImage / oInfoHeader.biHeight;
    unsigned char *third = (unsigned char*)malloc(myline * 8 * oInfoHeader.biHeight);
    unsigned char *forth = (unsigned char*)malloc(myline * oInfoHeader.biHeight);
    unsigned char *img = (unsigned char*)malloc(oInfoHeader.biSizeImage);
    

    // first step
    int i,j,k,t = -1;
    int temp = infoHeader.biSizeImage / infoHeader.biHeight;
    for(i = 0; i < infoHeader.biHeight; i++) {
        for(j = 0; j < temp; j++) {
            for(k = 0; k < 8; k++) {
                if(j*8 + k < oInfoHeader.biHeight) {
                    first[++t] = data[i * temp + j] >> (8-1-k) & 1;          
                }
            }
        }
    }
    
    // second step
    // rotate
    t = -1;
    for(i = 0; i < oInfoHeader.biHeight; i++) {
        for(j = 0; j < infoHeader.biHeight; j++) {
            second[++t] = first[oInfoHeader.biHeight*j + oInfoHeader.biHeight - i - 1];
        }
    }
    
    // step three
    // fill with 0's
    t = -1;
    for(i = 0; i < oInfoHeader.biHeight; i++) {
        for(j = 0; j < infoHeader.biHeight; j++) {
            third[++t] = second[i*infoHeader.biHeight + j];
        }
        for(k = infoHeader.biHeight; k < myline * 8; k++) {
            third[++t] = 0;
        }
    }
    
    // step four
    // transfer
    int u = -1;
    int m = -1;
    for(i = 0; i < oInfoHeader.biHeight; i++) {
        for(j = 0; j < myline * 8; j++) {
            int sum = 0;
            for(k = 0; k < 8; k++) {
                sum += pow(2,8-k-1)*third[++m%t];
            }
            forth[++u] = sum;
        }
    }
    
    fwrite( forth , 1 , myline * oInfoHeader.biHeight , of );
    
    free(img);
    free(data);
    
    fclose(f);
    fclose(of);
     
}

int main() {
    cw90("original.bmp","ttt.bmp");
    system("pause");
    return 0;
}


Before:



after:



代码在vs2010, os X 10.8.0 上测试通过。在windows上运行失败可将 typedef unsigned int LONG 修改成 typedef unsigned long LONG.

[上述代码适用于单色BMP文件](biBitCount = 1)



上述方法有问题,正确的请参[http://201211131343.iteye.com/blog/1992364
]

你可能感兴趣的:(C/C++)