final_bmp

This commit is contained in:
SunnyGor 2023-01-18 10:05:06 +08:00
parent 31d29665fc
commit 9a5bf18e20
16 changed files with 723 additions and 0 deletions

20
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -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
}

47
.vscode/settings.json vendored Normal file
View File

@ -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"
}
}

BIN
Baby.tux-black-800x800.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
bmp_24(done).bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
bmp_24.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
bw2x1(done).bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 B

BIN
bw2x1.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 B

BIN
bw2x3(done).bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 B

BIN
bw2x3.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 B

285
test.cpp Normal file
View File

@ -0,0 +1,285 @@
#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){//不存在,有可能是旋轉
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;
}

BIN
test.exe Normal file

Binary file not shown.

71
test/Image.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "Image.h"
#include <iostream>
#include <fstream>
#include <windows.h>
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<Color>(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";
}

27
test/Image.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
#include <vector>
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<Color> m_colors;
};

17
test/bmp.cpp Normal file
View File

@ -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;
}

256
transform.cpp Normal file
View File

@ -0,0 +1,256 @@
#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;
}

BIN
transform.exe Normal file

Binary file not shown.