#include <fstream>
#include <ios>
#include <ctime>
#include <iostream>
#include <windows.h>
class MyBitmap {
BITMAPFILEHEADER header_;
BITMAPINFOHEADER info_;
bool loaded_;
char* pixels_;
size_t data_size_;
size_t row_padded_;
public:
MyBitmap(const char* fileName) {
loaded_ = false;
pixels_ = 0;
std::ifstream bmp(fileName, std::ios::binary);
if (!bmp) {
return;
}
bmp.read((char*)&header_, sizeof(header_));
if (!bmp) {
return;
}
if (header_.bfType != 'MB') {
std::cout << "Format is not supported" << std::endl;
return;
}
bmp.read((char*)&info_, sizeof(info_));
if (!bmp) {
return;
}
if (info_.biBitCount != 24) {
std::cout << "Format is not supported" << std::endl;
return;
};
row_padded_ = (info_.biWidth * 3 + 3) & (~3);
int height = info_.biHeight;
data_size_ = row_padded_ * height;
pixels_ = new char[data_size_];
bmp.read(pixels_, data_size_);
if (bmp) {
loaded_ = true;
}
return;
}
bool Save(const char* fileName) {
if (!loaded_) {
return false;
}
std::ofstream f(fileName, std::ios::binary);
if (!f) {
return false;
}
f.write((char*)&header_, sizeof(header_));
f.write((char*)&info_, sizeof(info_));
f.write(pixels_, data_size_);
if (f) {
return true;
}
return false;
}
void AddBorderInside(int borderSize = 15) {
for (int i = 0; i < info_.biWidth; i++) {
for (int j = 0; j < info_.biHeight; j++) {
if (i < borderSize || i >= info_.biWidth - borderSize
|| j < borderSize || j >= info_.biHeight - borderSize) {
int pos = row_padded_* j + i * 3;
pixels_[pos] = rand() % 256;
pixels_[pos + 1] = rand() % 256;
pixels_[pos + 2] = rand() % 256;
}
}
}
}
void AddBorderOutside(int borderSize = 15) {
int new_width = info_.biWidth + borderSize * 2;
int new_row_padded = (new_width * 3 + 3) & (~3);
int new_height = info_.biHeight + borderSize * 2;
int new_data_size = new_row_padded * new_height;
char* new_pixels_ = new char[new_data_size];
for (int i = 0; i < info_.biHeight; i++) {
int old_pos = row_padded_* i;
int new_pos = new_row_padded * (borderSize+i) +3 * borderSize;
memcpy(new_pixels_ + new_pos, pixels_ + old_pos, info_.biWidth * 3);
}
delete[] pixels_;
info_.biWidth = new_width;
info_.biHeight = new_height;
pixels_ = new_pixels_;
row_padded_ = new_row_padded;
data_size_ = new_data_size;
AddBorderInside(borderSize);
}
bool IsLoaded() const {
return loaded_;
}
~MyBitmap() {
delete[] pixels_;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
srand(time(0));
MyBitmap bmp("input.bmp");
if (!bmp.IsLoaded()) {
std::cout << "Unable to load bitmap" << std::endl;
return 1;
}
bmp.AddBorderOutside();
if (!bmp.Save("output.bmp")) {
std::cout << "Unable to save bitmap" << std::endl;
}
return 0;
}