final_bmp/transform.cpp

256 lines
8.6 KiB
C++
Raw Blame History

#include <iostream>
#include <fstream>
#include <windows.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <algorithm>
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){//不存<E4B88D>?
error(2);
return 0;
}
else if(check_out == string::npos){//不存<E4B88D>?
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;
}