@Muriam

Работа с графикой. С++ builder. Как нарисовать рамку вокруг рисунка?

Как пpеобpазовать BMP файл, создав вокpуг него pамку из пикселей случайного цвета? Шиpина рамки - 15 пикселей.
  • Вопрос задан
  • 740 просмотров
Пригласить эксперта
Ответы на вопрос 1
SerJook
@SerJook
кодер
В зависимости от того, какая рамка вам нужна, я сделал в классе MyBitmap 2 метода: AddBorderOutside() и AddBorderInside().
Я без понятия, скомпилируется ли код в C++ Builder, потому что я использовал Visual Studio.

Код под спойлером
#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;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы