Step by step use standard c to write a cross-platform image processing library_turn an image into a reverse image

Continuing from the previous chapter , use standard c to write a cross-platform image processing library step by step . This chapter will introduce how to turn an image into an inverted image. The principle is very simple. You only need to invert the RGB three colors on each pixel. ! becomes a negative number!

Its formula is:

s = -r-g-b

Conversion method:

First define a macro function. Its function is obvious. It converts an integer into a negative number signed to clearly tell the compiler that the converted type is a signed negative number, but the converted type is not necessarily signed. It just tells the compiler to use signed type operation, if the actual type cannot store signed data, it will be 0 after the operation:

#define POSITIVE_TO_NEGATIVE(x) x = (signed)-x

Implementation function:

//Convert the image to a reverse image_This method can only be used for true color images
int image_reverse_rgb(struct image_struct** im){
	if ((*im) == NULL){ //Determine whether the passed image pointer is empty
		return -1;
	}
	//Converting to a reverse image is very simple, just convert the pixels in each image to negative, note that in a 24-bit image file, one byte corresponds to one color value and three bytes are one Complete pixels, so we can convert pixel by pixel
	//The algorithm formula is: S=-RGB
	for (int i = 0; i < (*im)->image_Data_Size; ++i){
			if ((*im)->image_Data[i] == (int)0){ //If it is equal to 0, it will not be processed
				continue; // start the next loop
			}//i*(*im)->image_Width + j
			POSITIVE_TO_NEGATIVE((*im)->image_Data[i]);
	}
	return 0;
}

test:

int main(){
	image *imga;
	image_malloc(&imga);
	image_load(&imga, "e:\\timg (1).bmp");
	image_reverse_rgb(&imga);
	image_save_file(&imga,"e:\\1.bmp");
	getchar();
}

operation result:



Full code:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
// macro definition
// positive to negative
#define POSITIVE_TO_NEGATIVE(x) x = (signed)-x
//type definition
//8bit  
typedef char UINT_8;
//16bit  
typedef char UINT_16[2];
//22bit  
typedef char UINT_22[3];
//256bit  
typedef char UINT_256[256];
//32bit  
typedef int  UINT_32;
//data  
typedef char* DATA;
//64 fbit  
typedef double FUINT_64;
//16bit int  
typedef short SUINT_16;
//struct
//Image structure, to prevent the structure from aligning, otherwise there will be an error when reading the file stream, so use the pragma command to force the alignment
#pragma pack (1)  
typedef struct image_struct{
	UINT_16 image_pil; //File identifier  
	UINT_32 image_Size; //File size  
	UINT_16 image_Reserved1; //No need to ask  
	UINT_16 image_Reserved2; //No need to ask  
	UINT_32 image_Offbits; // offset from header file to image data  
	UINT_32 image_Stsize; //The required size of the structure  
	UINT_32 image_Width; //image width  
	UINT_32 image_Height; //image height  
	UINT_16 image_Planes; //Number of target device planes  
	SUINT_16 image_Bitcount; //How many bits the pixel occupies  
	UINT_32 image_Compression; //Image compression type  
	UINT_32 image_Sizeimage; //The size of the image  
	UINT_32 image_Xpelspermeter; //horizontal resolution  
	UINT_32 image_Ypelspermeter; //Vertical resolution  
	UINT_32 image_ClrUsed; //Palette index number  
	UINT_32 image_Clrlmportant; //The image displays the number of important color indices  
	DATA image_Data; //image data
	UINT_32 image_Data_Size; //Image data size
}image;
#pragma pack ()  
//function
//load image
int image_load(struct image_struct** im, char *path){
	FILE *image_path_fp;
	image_path_fp = fopen(path, "rb");
	if (image_path_fp == NULL){
		return -1;
	}
	//get file size
	fseek(image_path_fp, 0, SEEK_END); //Locate to the end of the file
	int nFileLen = ftell(image_path_fp); //File length
	fseek(image_path_fp, 0, SEEK_SET); //Restore to the file header to prevent reading data from the end of the file
	//read header information
	if (fread((*im), (sizeof(struct image_struct) - ((sizeof(DATA/*image_Data*/)+(sizeof(UINT_32)/*image_Data_Size*/)))/*Do not read the data temporarily, cannot Get data offset from header file to prevent data clutter */), 1, image_path_fp) == 0){
		return -2;
	}
	// allocate memory to the data variable
	(*im)->image_Data = (DATA)malloc(nFileLen-(*im)->image_Offbits/*full data size*/);
	/ / Determine whether the allocation is successful
	if ((*im)->image_Data == NULL){ // malloc returns NULL if there is no free heap memory
		return -3;
	}
	//read data
	// Move the file pointer to the file header information before reading, and find the correct data storage area
	fseek(image_path_fp, 0, SEEK_SET); //Restore to the file header, because fread has been done once, so the data file pointer has changed
	fseek(image_path_fp, (*im)->image_Offbits, SEEK_CUR); //Ignore header data
	if (fread((*im)->image_Data, (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/), 1, image_path_fp) == 0){
		return -4;
	}
	//Save the file size for easy read and write operations
	(*im)->image_Data_Size = (nFileLen - (*im)->image_Offbits/*file - off = actual size*/);
	//The file pointer is released to prevent the critical resources of the file kernel from being occupied
	fclose(image_path_fp);
	image_path_fp = NULL;
	return 0;
}
// allocate memory for image data
int image_malloc(struct image_struct** im){
	*im = (struct image_struct*)malloc(sizeof(struct image_struct));
	if (*im == NULL){
		return -1;
	}
	return 0;
}
//Convert the image to a reverse image_This method can only be used for true color images
int image_reverse_rgb(struct image_struct** im){
	if ((*im) == NULL){ //Determine whether the passed image pointer is empty
		return -1;
	}
	//Converting to a reverse image is very simple, just convert the pixels in each image to negative, note that in a 24-bit image file, one byte corresponds to one color value and three bytes are one Complete pixels, so we can convert pixel by pixel
	//The algorithm formula is: S=-RGB
	for (int i = 0; i < (*im)->image_Data_Size; ++i){
			if ((*im)->image_Data[i] == (int)0){ //If it is equal to 0, it will not be processed
				continue; // start the next loop
			}//i*(*im)->image_Width + j
			POSITIVE_TO_NEGATIVE((*im)->image_Data[i]);
	}
	return 0;
}
//save image data to file
int image_save_file(struct image_struct** im, char *path){
	FILE* file_fp = fopen(path, "wb+"); //Open in binary read-write mode
	if (file_fp == NULL){ //Determine whether the file pointer is empty
		return -1;
	}
	// write header information
	fwrite((*im), (*im)->image_Offbits/*Directly write the offset size of the header file to the data*/, 1, file_fp);
	//write file data
	fwrite((*im)->image_Data, (*im)->image_Data_Size, 1, file_fp);
	return 0;

}
int main(){
	image *imga;
	image_malloc(&imga);
	image_load(&imga, "e:\\timg (1).bmp");
	image_reverse_rgb(&imga);
	image_save_file(&imga,"e:\\1.bmp");
	getchar();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325773099&siteId=291194637