单线程操作图片
代码
ImageStuff.h
struct ImgProp
{
int Hpixels;
int Vpixels;
unsigned char HeaderInfo[54];
unsigned long int Hbytes;
};
struct Pixel
{
unsigned char R;
unsigned char G;
unsigned char B;
};
unsigned char** ReadBMP(char* );
void WriteBMP(unsigned char** , char*);
extern struct ImgProp ip;
ImageStuff.c
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "ImageStuff.h"
unsigned char** ReadBMP(char* filename)
{
int i;
FILE* f = fopen(filename, "rb");
if(f == NULL)
{
printf("\n\n%s NOT FOUND\n\n",filename);
exit(1);
}
unsigned char HeaderInfo[54];
fread(HeaderInfo, sizeof(unsigned char), 54, f); // read the 54-byte header
// extract image height and width from header
int width = *(int*)&HeaderInfo[18];
int height = *(int*)&HeaderInfo[22];
//copy header for re-use
for(i=0; i<54; i++) {
ip.HeaderInfo[i] = HeaderInfo[i];
}
ip.Vpixels = height;
ip.Hpixels = width;
int RowBytes = (width*3 + 3) & (~3);
ip.Hbytes = RowBytes;
printf("\n Input BMP File name: %20s (%u x %u)",filename,ip.Hpixels,ip.Vpixels);
unsigned char tmp;
unsigned char **TheImage = (unsigned char **)malloc(height * sizeof(unsigned char*));
for(i=0; i<height; i++) {
TheImage[i] = (unsigned char *)malloc(RowBytes * sizeof(unsigned char));
}
for(i = 0; i < height; i++) {
fread(TheImage[i], sizeof(unsigned char), RowBytes, f);
}
fclose(f);
return TheImage; // remember to free() it in caller!
}
void WriteBMP(unsigned char** img, char* filename)
{
FILE* f = fopen(filename, "wb");
if(f == NULL)
{
printf("\n\nFILE CREATION ERROR: %s\n\n",filename);
exit(1);
}
unsigned long int x,y;
char temp;
//write header
for(x=0; x<54; x++) {
fputc(ip.HeaderInfo[x],f);
}
//write data
for(x=0; x<ip.Vpixels; x++) {
for(y=0; y<ip.Hbytes; y++)
{
temp=img[x][y];
fputc(temp,f);
}
}
printf("\n Output BMP File name: %20s (%u x %u)",filename,ip.Hpixels,ip.Vpixels);
fclose(f);
}
imflip.c
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "ImageStuff.h"
#define REPS 129
struct ImgProp ip;
unsigned char** FlipImageV(unsigned char** img)
{
struct Pixel pix; //temp swap pixel
int row, col;
//vertical flip
for(col=0; col<ip.Hbytes; col+=3)
{
row = 0;
while(row<ip.Vpixels/2)
{
pix.B = img[row][col];
pix.G = img[row][col+1];
pix.R = img[row][col+2];
img[row][col] = img[ip.Vpixels-(row+1)][col];
img[row][col+1] = img[ip.Vpixels-(row+1)][col+1];
img[row][col+2] = img[ip.Vpixels-(row+1)][col+2];
img[ip.Vpixels-(row+1)][col] = pix.B;
img[ip.Vpixels-(row+1)][col+1] = pix.G;
img[ip.Vpixels-(row+1)][col+2] = pix.R;
row++;
}
}
return img;
}
unsigned char** FlipImageH(unsigned char** img)
{
struct Pixel pix; //temp swap pixel
int row, col;
//horizontal flip
for(row=0; row<ip.Vpixels; row++)
{
col = 0;
while(col<(ip.Hpixels*3)/2)
{
pix.B = img[row][col];
pix.G = img[row][col+1];
pix.R = img[row][col+2];
img[row][col] = img[row][ip.Hpixels*3-(col+3)];
img[row][col+1] = img[row][ip.Hpixels*3-(col+2)];
img[row][col+2] = img[row][ip.Hpixels*3-(col+1)];
img[row][ip.Hpixels*3-(col+3)] = pix.B;
img[row][ip.Hpixels*3-(col+2)] = pix.G;
img[row][ip.Hpixels*3-(col+1)] = pix.R;
col+=3;
}
}
return img;
}
int main(int argc, char** argv)
{
if(argc != 4)
{
printf("\n\nUsage: imflip [input] [output] [V | H]");
printf("\n\nExample: imflip square.bmp square_h.bmp h\n\n");
return 0;
}
unsigned char** data = ReadBMP(argv[1]);
double timer;
unsigned int a;
clock_t start,stop;
start = clock();
switch (argv[3][0]){
case 'v' :
case 'V' : for(a=0; a<REPS; a++) data = FlipImageV(data); break;
case 'h' :
case 'H' : for(a=0; a<REPS; a++) data = FlipImageH(data); break;
default : printf("\nINVALID OPTION\n"); return 0;
}
stop = clock();
timer = 1000*((double)(stop-start))/(double)CLOCKS_PER_SEC/(double)REPS;
//merge with header and write to file
WriteBMP(data, argv[2]);
// free() the allocated memory for the image
for(int i = 0; i < ip.Vpixels; i++) { free(data[i]); }
free(data);
printf("\n\nTotal execution time: %9.4f ms",timer);
printf(" (%7.3f ns per pixel)\n", 1000000*timer/(double)(ip.Hpixels*ip.Vpixels));
return 0;
}
编译
gcc imflip.c ImageStuff.c -o imflip
运行效果
垂直翻转(V)
./imflip nature_monte.bmp nature_monte_V.bmp V
原图
垂直翻转后:
水平翻转(H)
./imflip nature_monte.bmp nature_monte_H.bmp H
原图
水平翻转后