#include #include #include #include #include #include #include using namespace std; typedef unsigned char uch; void error(int x){ switch (x) { case 1: fprintf(stderr, "Usage: ./transform.exe infile outfile width*height!\n"); break; case 2: fprintf(stderr, "Format of infile is wrong, pleace check it and try again!\n"); break; case 3: fprintf(stderr, "Format of outfile is wrong, pleace check it and try again!\n"); break; case 4: fprintf(stderr, "Please use width*height or angle format at the end!\n"); break; default: break; } } bool isNumber(const string& str) { return !str.empty() && std::find_if(str.begin(), str.end(), [](unsigned char c) { return !std::isdigit(c); }) == str.end(); } char* input_file = new char[100]; char* output_file = new char[100]; uint32_t old_width, old_height, bit; uint32_t new_width, new_height; int situation = 0; int angle = 0; int main(int argc, char* argv[]){ BITMAPFILEHEADER old_head; BITMAPINFOHEADER old_info; ifstream infile; if(argc != 4){ error(1); return 0; } else{ input_file = argv[1]; output_file = argv[2]; string funtion = argv[3]; string special_symbol = "*"; string special_words = ".bmp"; string::size_type check_in, check_out, func; check_in = ((string)input_file).find(special_words); check_out = ((string)output_file).find(special_words); func = funtion.find(special_symbol); infile.open(input_file, ios::in | ios::binary); infile.read((char*)&old_head, sizeof(BITMAPFILEHEADER)); infile.read((char*)&old_info, sizeof(BITMAPINFOHEADER)); uint32_t old_width = old_info.biWidth; uint32_t old_height = old_info.biHeight; uint16_t bit = old_info.biBitCount; if(check_in == string::npos){//不存?? error(2); return 0; } else if(check_out == string::npos){//不存?? error(3); return 0; } if(func == string::npos){//不存在,有可能是旋轉 if(isNumber(funtion)){ new_width = old_width; new_height = old_height; angle = stoi(funtion); if(angle == 90){ situation = 1; new_width = old_height; new_height = old_width; } else if(angle == 180){ situation = 2; new_width = old_width; new_height = old_height; } else if(angle == 270){ situation = 3; new_width = old_height; new_height = old_width; } else{error(4);return 0;} } else{error(4);return 0;} } else{ situation = 0; int current = 0; int pos = funtion.find_first_of(special_symbol, current); new_width = atoi((funtion.substr(0, funtion.find(special_symbol))).c_str()); new_height = atoi((funtion.substr(funtion.find(special_symbol) + 1, funtion.length())).c_str()); } } cout << situation << endl; if(old_head.bfType != 0x4d42){ cout << "error" << endl; infile.close(); return 0; } unsigned char raw[old_height][old_width][3] = {}; // cout << old_info. << endl; int padding = (4 - (old_width * 3) % 4) % 4; for(int y = old_height-1; y >= 0; --y) { for(int x = 0; x < old_width; ++x) { if(bit == 24) { unsigned char colour[3]; infile.read((char*)raw[y][x], 3); } } infile.ignore(padding); } infile.close(); //--------------長、寬??----------------- // float radio_w, radio_h; // printf("倍數(w)??"); // cin >> radio_w; // printf("倍數(h)??"); // cin >> radio_h; // uint32_t new_width = (uint32_t)floor(radio_w*old_width); // uint32_t new_height = (uint32_t)floor(radio_h*old_height); //--------------特定長、寬----------------- // uint32_t new_width, new_height; // printf("倍數(w)??"); // scanf("%d", &new_width); // printf("倍數(h)??"); // scanf("%d", &new_height); float radio_w = (float)new_width/old_width; float radio_h = (float)new_height/old_height; ofstream outfile; outfile.open(output_file, ios::out | ios::binary); BITMAPFILEHEADER new_head; BITMAPINFOHEADER new_info; new_head.bfType = 0x4d42; new_head.bfReserved1 = 0; new_head.bfReserved2 = 0; new_head.bfOffBits = 54; new_head.bfSize = new_head.bfOffBits + new_width*new_height * bit/8; if(bit==8){new_head.bfSize += 1024, new_head.bfOffBits += 1024;} new_info.biSize = 40; new_info.biPlanes = 1; new_info.biCompression = 0; new_info.biXPelsPerMeter = 0; new_info.biYPelsPerMeter = 0; new_info.biClrUsed = 0; new_info.biClrImportant = 0; new_info.biWidth = new_width; new_info.biHeight = new_height; new_info.biBitCount = bit; new_info.biSizeImage = new_width*new_height*bit/8; outfile.write((char*)&new_head, sizeof(new_head)); outfile.write((char*)&new_info, sizeof(new_info)); // cout << "\nnew_width : " << new_width << endl; // cout << "new_height : " << new_height << endl; padding = (4 - (new_width * 3) % 4) % 4; unsigned char bmpPad[3] = {0, 0, 0}; switch (situation) { case 0: //---------------------------resize------------------------- for(int y = new_height-1; y >= 0; --y){ for(int x = 0; x < new_width; ++x){ if(bit == 24) { unsigned char b = raw[(int)(y/radio_h)][(int)(x/radio_w)][2]; unsigned char g = raw[(int)(y/radio_h)][(int)(x/radio_w)][1]; unsigned char r = raw[(int)(y/radio_h)][(int)(x/radio_w)][0]; unsigned char color[] = {r, g, b}; outfile.write((char*)color, 3); } // else if(bit == 8){ // outfile.write((char*)&raw[i][j], sizeof(char*)); // } } outfile.write((char*)bmpPad, padding); } break; case 1: //---------------------------turn 90------------------------- for(int x = 0; x < new_width; ++x){ for(int y = 0; y < new_height; ++y){ if(bit == 24) { unsigned char b = raw[(int)(y/radio_h)][(int)(x/radio_w)][2]; unsigned char g = raw[(int)(y/radio_h)][(int)(x/radio_w)][1]; unsigned char r = raw[(int)(y/radio_h)][(int)(x/radio_w)][0]; unsigned char color[] = {r, g, b}; outfile.write((char*)color, 3); } // else if(bit == 8){ // outfile.write((char*)&raw[i][j], sizeof(char*)); // } } outfile.write((char*)bmpPad, padding); } outfile.close(); return 0; break; case 2: //---------------------------turn 180------------------------- for(int y = 0; y < new_height; ++y){ for(int x = new_width-1; x >= 0; --x){ if(bit == 24) { unsigned char b = raw[(int)(y/radio_h)][(int)(x/radio_w)][2]; unsigned char g = raw[(int)(y/radio_h)][(int)(x/radio_w)][1]; unsigned char r = raw[(int)(y/radio_h)][(int)(x/radio_w)][0]; unsigned char color[] = {r, g, b}; outfile.write((char*)color, 3); } // else if(bit == 8){ // outfile.write((char*)&raw[i][j], sizeof(char*)); // } } outfile.write((char*)bmpPad, padding); } outfile.close(); return 0; break; case 3: //---------------------------turn 270------------------------- for(int x = new_width - 1; x >= 0; --x){ for(int y = new_height-1; y >= 0; --y){ if(bit == 24) { unsigned char b = raw[(int)(y/radio_h)][(int)(x/radio_w)][2]; unsigned char g = raw[(int)(y/radio_h)][(int)(x/radio_w)][1]; unsigned char r = raw[(int)(y/radio_h)][(int)(x/radio_w)][0]; unsigned char color[] = {r, g, b}; outfile.write((char*)color, 3); } // else if(bit == 8){ // outfile.write((char*)&raw[i][j], sizeof(char*)); // } } outfile.write((char*)bmpPad, padding); } outfile.close(); return 0; break; default: return 0; break; } //----------------------------------------------------------------------------- outfile.close(); return 0; }