/****************************************************************************
* Func: rotate_pgm *
* *
* Desc: rotate an image some arbitrary angle. New pixels are generated *
* using bilinear interpolation *
* *
* Params: buffer - pointer to image in memory *
* fileout - name of output file *
* rows - number of rows in source image *
* cols - number of columns in source image *
* angle - angle of rotation (in degrees) *
****************************************************************************/
void rotate_pgm(image_ptr buffer, char *fileout, int rows, int cols, float angle)
{
float angle2; /* 90 degrees - angle */
long x,y; /* column and row indices */
int index; /* index into output line buffer */
unsigned long source_add; /* address of source pixels */
float floatx, floaty; /* floating point values of source x and y */
int intx, inty; /* integer value of source x and y */
int centerx, centery; /* center of new image */
float EWweight, NSweight; /* linear weights for interpolation */
float NW, NE, SW, SE; /* northwest, northeast, southwest, southeast*/
float top, bottom; /* interpolated top and bottom values */
float cosine, sine; /* cosine and sine of angle */
unsigned char *line_buff; /* output line buffer */
int new_rows, new_cols; /* number of rows and columns of new image */
FILE *fp; /* output file pointer */
int xdiff, ydiff; /* difference between new and old rows and cols */
/* open new output file */
if((fp=fopen(fileout, "wb")) == NULL)
{
printf("Unable to open %s for output\n",fileout);
exit(1);
}
while(angle >= 360.0)
angle -=360.0;
/* miscellaneous trig */
angle *= ((double) 3.14159265/(double) 180.0); /* convert to RADs */
angle2 = 1.570796327 - angle;
cosine = cos(angle);
sine = sin(angle);
/* determine new size of output image */
new_cols = rows * fabs(cos(angle2)) + cols * fabs(cosine);
new_rows = rows * fabs(cosine) + cols * fabs(cos(angle2));
centerx = cols/2;
centery = rows/2;
xdiff = (new_cols - cols)/2;
ydiff = (new_rows - rows)/2;
/* print out the portable bitmap header */
fprintf(fp, "P5\n%d %d\n255\n", new_cols, new_rows);
line_buff = (unsigned char *) malloc(new_cols);
for(y=-1*ydiff; y<(new_rows-ydiff); y++)
{
index = 0;
for(x=-1*xdiff; x<(new_cols-xdiff); x++)
{
floatx = (x-centerx) * cosine + (y-centery) * sine;
floatx += centerx;
floaty = (y-centery) * cosine - (x-centerx) * sine;
floaty += centery;
intx = (int) floatx;
inty = (int) floaty;
/* check if pixel is outside of source image */
if((intx < 0) || (intx >= cols-1) || (inty < 0) || (inty >= rows-1))
line_buff[index++] = 255;
else /* interpolate new value */
{
EWweight = floatx - (float) intx;
NSweight = floaty - (float) inty;
source_add = (unsigned long) inty * cols + intx;
NW = (float) buffer[source_add];
NE = (float) buffer[source_add+1];
SW = (float) buffer[source_add+cols];
SE = (float) buffer[source_add+cols+1];
top = NW + EWweight*(NE-NW);
bottom = SW + EWweight*(SE-SW);
line_buff[index++] = (char) (top + NSweight*(bottom-top));
}
}
fwrite(line_buff, 1, new_cols, fp);
}
fclose(fp);
}
rotate an image 图像旋转代码
最新推荐文章于 2021-11-18 17:36:35 发布