final_bmp/test.cpp

285 lines
9.1 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");
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){//²»´æÔÚ£¬ÓпÉÄÜÊÇÐýÞD
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();
//--------------éL¡¢Œ??-----------------
// 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);
//--------------ÌØ¶¨éL¡¢Œ-----------------
// 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;
}