您的位置:首页 > 其它

矩阵论还真有用:图片缩放旋转

2016-07-23 19:55 260 查看
#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <math.h>

#define SCREEN_W 800

#define SCREEN_H 480

//#pragma pack(1)

typedef struct{

    short  bfType;     //bfType(2字节),这里恒定等于&H4D42,ASCII字符'BM'

    unsigned int bfSize;     //文件大小,以4字节为单位

    short  bfReserve1; //备用

    short  bfReserve2; //备用

    unsigned int bfoffBits;  //数据区在文件中的位置偏移量

}__attribute__((packed))BITMAPFILEHEADER;   //文件头结构体,14字节

typedef struct{

    long bitSize;    //位图信息头大小 本结构体大小 40btye

    long biWidth;    //图象宽度,像素单位

    long biHeight;   //图象高度,像素单位

    short  biPlanes;   //位平面树=1

    short  biBitCount; //单位像素的位数,表示bmp图片的颜色位数,即24位图、32位图

    long biCompression;  //图片的压缩属性,bmp图片是不压缩的,等于0

    long biSizeImage;    //表示bmp图片数据区的大小,当上一个属性biCompression等于0时,这里的值可以省略不填

    long biXPlosPerMeter;//水平分辨率,可省略

    long biYPlosPerMeter;//垂直分辨率,可省略

    long biClrUsed;      //表示使用了多少个颜色索引表,一般biBitCount属性小于16才会用到,

                                  //等于0时表示有2^biBitCount个颜色索引表

    long biClrImportant; //表示有多少个重要的颜色,等于0时表示所有颜色都很重要

}BITMAPINFOHEADER;       //位图信息头,40字节

typedef struct tagRGBQUAD {

    unsigned char rgbBlue;     // 蓝色的亮度(值范围为0-255)

    unsigned char rgbGreen;    // 绿色的亮度(值范围为0-255)

    unsigned char rgbRed;      // 红色的亮度(值范围为0-255)

    unsigned char rgbReserved; // 保留,必须为0

} RGBQUAD;

typedef struct tagBITMAPINFO {

    BITMAPINFOHEADER bmiHeader; // 位图信息头

    RGBQUAD bmiColors[1];       // 颜色表

} BITMAPINFO;

//#pragma pack()

struct pic_obj {

    int nxp,nyp;

    unsigned bmap[256];

    unsigned char *data;        

};

struct pic_obj pics[2] = {0};

//将图片读入内存

int init_pics(const char *file, int num)

{

    int i, j;

    int nread;

    FILE *fp;

    char buf[1024*4];

    BITMAPFILEHEADER header;

    BITMAPINFOHEADER info;

    

    fp = fopen(file, "rb");

    if(fp == NULL){

        printf("open pic failed!\n");

    }

    nread = fread(&header, 1, sizeof(BITMAPFILEHEADER), fp);

    if(nread != sizeof(BITMAPFILEHEADER)){

        printf("read header fail\n");

    }

    

    nread = fread(&info, 1, sizeof(BITMAPINFOHEADER), fp);

    if(nread != sizeof(BITMAPINFOHEADER)){

        printf("read info fail\n");

    }

    nread = fread(buf, 1, sizeof(RGBQUAD)*256, fp);    

    if(nread != sizeof(RGBQUAD)*256){

        printf("read pic map!\n");

    }

    pics[num].nxp = info.biWidth;

    pics[num].nyp = info.biHeight;

    unsigned int value;

    RGBQUAD *rgbmap = buf;

    pics[num].data = (unsigned char *)malloc(header.bfSize - header.bfoffBits);

    nread = fread(pics[num].data, 1, header.bfSize - header.bfoffBits, fp); 

    if(nread != header.bfSize - header.bfoffBits){

        printf("read pic data failed!\n");

    }

    fclose(fp);

    return 0;

}

//x = x*c - y*s

//y = x*s + y*c

unsigned char gbuf[10*1024*1024] = {0,};

float cbuf[2000]={0,};

float sbuf[2000]={0,};

float scbuf[2000]={0,};

int main(int argc,char *argv[])

{

    int i,j;    

    int ang = atoi(argv[1]);

    float scal = (float)atoi(argv[2])/100;

    init_pics("./in.bmp",0);

    

    float c = cos(ang*3.1415926/180);

    float s = sin(ang*3.1415926/180);

    int tmp = sizeof(sbuf)/sizeof(sbuf[0])/2;

    for(i=0;i<sizeof(cbuf)/sizeof(cbuf[0]);i++){

        cbuf[i] = (i-tmp)*c;

        sbuf[i] = (i-tmp)*s;

        scbuf[i] = (i-tmp)*scal;

    }    

    printf("%f,%f,%f\n",c,s,scal);

    printf("%f,%f,%f\n",cbuf[50],sbuf[50],scal);

    printf("%f,%f,%f\n",cbuf[100],sbuf[100],scal);

    

    int w = pics[0].nxp;

    int h = pics[0].nyp;

    

    char *dat = malloc(w*h);

    memset(dat,0,w*h);

    

    int w2 = w/2;

    int h2 = h/2;    

    

    int jj = -1*w;

    unsigned char *ptr[1000]={0,}; 

    for(i=0; i < h; i++){

        ptr[i] = &pics[0].data[i*w];

    }

    //c=0;

    //s=1;

    for(i=0; i < h; i++){

        jj += w;

        for(j=0; j < w; j++){

            int xx,yy,xc,yc;

            

            //xx = j - w/2;

            //yy = h/2 - i;

            //xc = xx*c - yy*s;

            //yc = xx*s + yy*c;

            //xc = xc*scal + w/2;

            //yc = h/2 + yc*scal;

            

            xx = j - w2;

            yy = h2 - i;

            xc = cbuf[xx+tmp] - sbuf[yy+tmp];

            yc = sbuf[xx+tmp] + cbuf[yy+tmp];

            xc = scbuf[xc+tmp] + w2;

            yc = h2 + scbuf[yc+tmp];

            if(xc >= 0 && xc < w && yc >= 0 && yc < h){

                //dat[(h-yc)*w+xc] = pics[0].data[i*w+j];

                //dat[jj+j] = pics[0].data[(h-yc)*w+xc];

                dat[jj+j] = ptr[h-yc-1][xc];

            }

            

        }

    }

    

    #if 0

    for(i=1; i < h-1; i++){

        for(j=1; j < w-1; j++){

            if(dat[i*w+j] == 0){

                //dat[i*800+j] = (dat[i*800+j+1]+dat[i*800+j-1]+

                //dat[(i+1)*800+j]+dat[(i-1)*800+j])/4;

                dat[i*w+j] = dat[(i+1)*w+j];

            }            

        }

    }

    #endif

    

    FILE *outfp = fopen("out.bmp","w+");

    FILE *infp = fopen("in.bmp","r+");

    

    fread(gbuf,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256,1,infp);

    fwrite(gbuf,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256,1,outfp);

    

    fwrite(dat,w*h,1,outfp);

    free(dat);

    fclose(infp);

    fclose(outfp);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: