diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..b4250d8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "compilerPath": "C:\\MinGW\\bin\\gcc.exe", + "cStandard": "c11", + "cppStandard": "gnu++14", + "intelliSenseMode": "windows-gcc-x86" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f9701df --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,47 @@ +{ + "files.associations": { + "new": "cpp", + "iosfwd": "cpp", + "ostream": "cpp", + "iostream": "cpp", + "*.tcc": "cpp", + "fstream": "cpp", + "cmath": "cpp", + "istream": "cpp", + "cstring": "cpp", + "array": "cpp", + "atomic": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "limits": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/Baby.tux-black-800x800.bmp b/Baby.tux-black-800x800.bmp new file mode 100644 index 0000000..63d10a4 Binary files /dev/null and b/Baby.tux-black-800x800.bmp differ diff --git a/bmp_24(done).bmp b/bmp_24(done).bmp new file mode 100644 index 0000000..9f7b36d Binary files /dev/null and b/bmp_24(done).bmp differ diff --git a/bmp_24.bmp b/bmp_24.bmp new file mode 100644 index 0000000..a4a6f68 Binary files /dev/null and b/bmp_24.bmp differ diff --git a/bw2x1(done).bmp b/bw2x1(done).bmp new file mode 100644 index 0000000..1d03893 Binary files /dev/null and b/bw2x1(done).bmp differ diff --git a/bw2x1.bmp b/bw2x1.bmp new file mode 100644 index 0000000..414a16b Binary files /dev/null and b/bw2x1.bmp differ diff --git a/bw2x3(done).bmp b/bw2x3(done).bmp new file mode 100644 index 0000000..9c21f87 Binary files /dev/null and b/bw2x3(done).bmp differ diff --git a/bw2x3.bmp b/bw2x3.bmp new file mode 100644 index 0000000..79e376f Binary files /dev/null and b/bw2x3.bmp differ diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..02e44cb --- /dev/null +++ b/test.cpp @@ -0,0 +1,285 @@ +#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; +} \ No newline at end of file diff --git a/test.exe b/test.exe new file mode 100644 index 0000000..1e22c53 Binary files /dev/null and b/test.exe differ diff --git a/test/Image.cpp b/test/Image.cpp new file mode 100644 index 0000000..1ed94f8 --- /dev/null +++ b/test/Image.cpp @@ -0,0 +1,71 @@ +#include "Image.h" +#include +#include +#include + +Color::Color() + : r(0),g(0),b(0) +{ +} + +Color::Color(float r, float g, float b) + : r(r),g(g),b(b) +{ +} + +Color::~Color(){} + +Image::Image(int width, int height) + : m_width(width), m_height(height), m_colors(std::vector(width * height)) +{} + +Image::~Image(){} + +Color Image::GetColor(int x, int y) const{ + return m_colors[y * m_width + x]; +} + +void Image::SetColor(const Color& color, int x, int y){ + m_colors[y * m_width + x].r = color.r; + m_colors[y * m_width + x].g = color.g; + m_colors[y * m_width + x].b = color.b; +} + +void Image::Export(const char* path) const{ + std::ofstream f; + f.open(path, std::ios::out | std::ios::binary); + + if (!f.is_open()){ + std::cout << "Error\n"; + return; + } + + unsigned char bmpPad[3] = {0, 0, 0}; + const int paddingAmount = ((4 - (m_width * 3) % 4) % 4); + + BITMAPFILEHEADER file_h; + BITMAPINFOHEADER info_h; + + const int fileHeaderSize = 14; + const int inforationHeaderSize = 40; + const int fileSize = fileHeaderSize + inforationHeaderSize + m_width * m_height * 3 + paddingAmount * m_height; + + f.write((char*)&file_h, fileHeaderSize); + f.write((char*)&info_h, inforationHeaderSize); + + for(int y = 0; y < m_height; y++){ + for(int x = 0; x < m_width; x++){ + unsigned char r = (unsigned char)(GetColor(x, y).r * 255.0f); + unsigned char g = (unsigned char)(GetColor(x, y).g * 255.0f); + unsigned char b = (unsigned char)(GetColor(x, y).b * 255.0f); + + unsigned char color[] = {b, g, r}; + + f.write((char*)color, 3); + } + f.write((char*)bmpPad, paddingAmount); + } + f.close(); + + std::cout << "done"; +} \ No newline at end of file diff --git a/test/Image.h b/test/Image.h new file mode 100644 index 0000000..cd899ab --- /dev/null +++ b/test/Image.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +struct Color{ + float r, g, b; + + Color(); + Color(float r, float g, float b); + ~Color(); +}; + +class Image{ +public: + Image(int width, int height); + ~Image(); + + Color GetColor(int x, int y) const; + void SetColor(const Color& color, int x, int y); + + void Export(const char* path) const; + +private: + int m_width; + int m_height; + std::vector m_colors; +}; diff --git a/test/bmp.cpp b/test/bmp.cpp new file mode 100644 index 0000000..36e02f8 --- /dev/null +++ b/test/bmp.cpp @@ -0,0 +1,17 @@ +#include "Image.h" + +int main(){ + const int width = 640; + const int height = 480; + + Image image(width, height); + + for(int y = 0; y < height; y++){ + for(int x = 0; x < width; x++){ + image.SetColor(Color((float)x / (float)width, 1.0f - ((float)x / (float)width), (float)y / (float)height), x, y); + } + } + + image.Export("image.bmp"); + return 0; +} \ No newline at end of file diff --git a/transform.cpp b/transform.cpp new file mode 100644 index 0000000..838d474 --- /dev/null +++ b/transform.cpp @@ -0,0 +1,256 @@ +#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"); + fprintf(stderr, "Usage: ./transform.exe infile outfile 0,90,180,270<--angle\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; + + case 5: + fprintf(stderr, "This program jsut allow 0,90,180,270, please try again!\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]; +ifstream infile; +uint32_t old_width, old_height, bit, new_width, new_height; +int situation = 0; +int angle = 0; +BITMAPFILEHEADER old_head; +BITMAPINFOHEADER old_info; + +int main(int argc, char* argv[]){ + 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); + + if(check_in == string::npos){//涓嶅瓨锟? + error(2); + return 0; + } + else if(check_out == string::npos){//涓嶅瓨锟? + error(3); + return 0; + } + if(func == string::npos){//涓嶅瓨鍦紝鏈夊彲鑳芥槸鏃嬭綁 + infile.open(input_file, ios::in | ios::binary); + infile.read((char*)&old_head, sizeof(BITMAPFILEHEADER)); + infile.read((char*)&old_info, sizeof(BITMAPINFOHEADER)); + old_width = old_info.biWidth; + old_height = old_info.biHeight; + bit = old_info.biBitCount; + if(isNumber(funtion)){ + 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(5);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()); + } + } + + // if(old_head.bfType != 0x4d42){ + // cout << "error" << endl; + // infile.close(); + // return 0; + // } + + unsigned char raw[old_height][old_width][3] = {}; + + 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(); + + printf("%x ", raw[0][0][0]); + printf("%x ", raw[1][0][0]); + 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}; +//---------------------------resize------------------------- + if(situation == 0){ + 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); + } + } +//---------------------------turn 90------------------------- + else if(situation == 1){ + for(int x = 0; x < new_height; ++x){ + for(int y = 0; y < new_width; ++y){ + if(bit == 24) { + printf("%x ", raw[y][x][0]); + 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*)); + // } + } + printf("\n"); + outfile.write((char*)bmpPad, padding); + } + } +//---------------------------turn 180------------------------- + else if(situation == 2){ + 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); + } + } +//---------------------------turn 270------------------------- + else if(situation == 3){ + 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; +} \ No newline at end of file diff --git a/transform.exe b/transform.exe new file mode 100644 index 0000000..08ec4cb Binary files /dev/null and b/transform.exe differ