Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Здравствуйте, Ильгиз. Математика - царица наук (Карл Гаусс). Изучение математики начинается с детского сада, когда нас учат считать и выполнять простые арифметические операции. Любой, даже самый простейший алгоритм будет связан с арифметическими...
Я хотел узнать математика это обязательно в программирование. Пять лет назад просто из любопытства я увлекся HTML потом изучил CSS и JvaScript потом изучил PHP и Java. Как то не задумывался и начал смотреть форумы и узнал что без математики не...
Все верно, но так же необходимо зайти в: Компоновщик -> Ввод -> Дополнительные зависимости Здесь необходимо нажать изменить и в Дополнительные зависимости прописать это: SDL2.lib SDL2main.lib SDL2test.lib Без этого не заработает. (MVS 2015)
Спасибо за реализацию, она действительно быстрая. Но не все линии отрисовывает в нужную сторону... Необходимо добавить проверку для случая X-линии if(y1 "<" y0) grad=-grad; и аналогично для Y-линии if(x1 "<" x0) grad=-grad; P.S. На...
Отличные уроки(учу GL по ним), только в renderScene нужно добавить очистку буфера цвета и буфера глубины. При изменении размеров треугольники размножаются)

Счетчики и рейтинг

Яндекс.Метрика Рейтинг@Mail.ru
Среда программирования: 
Code Blocks + MinGW

Чтобы сохранить картинку в формате BMP необходимо соблюдение особых правил, а именно соблюдения спецификаций заголовков файла BMP, в данном уроке мы рассматриваем наиболее часто встречаемую спецификацию с заголовками BMP и DIB (14 и 40 байт соответственно).
Прежде чем рассказать о том как строить заголовки BMP и DIB вооружимся необходимой функцией:

void int_to_bytes(char * arr, int n)
{
    for (int i = 0; i < 4; i++)
        arr[i] = (char)((n >> 8 * i) & 0xFF);
}

Она побайтово записывает значение целого числа в массив arr в ПЕРЕВЕРНУТОМ виде.

Для начала открываем файл:

ofstream os(filename, ofstream::binary);

Далее следует идентификатор того, что это файл BMP, а именно байты { 'B', 'M' }.
Идентификатор занимает 2 байта.
Запишем его в файл:

w[0] = 'B'; w[1] = 'M'; os.write(w, 2);

Далее идет размер файла в байтах, подсчитаем его так: (4*width*height + 14 + 40), т.к. на каждый пиксел мы будем тратить по 32 бита (4 байта) и 14 + 40 байтов на заголовки.
Идентификатор занимает 4 байта.
Запишем его в файл:

int_to_bytes(w, width*height*4 + 14 + 40); os.write(w, 4);

Далее следуют байты, специфические вашему приложению, мы в них не заинтересованы, пусть будет 0.
Идентификатор занимает 4 байта.
Запишем его в файл:

int_to_bytes(w, 0); os.write(w, 4);

Далее следует положение массива пикселов самой картинки. Т.к. на заголовки у нас уходит 14+40 байт, значит массив будет находится со смещением 54.
Идентификатор занимает 4 байта.
Запишем его в файл:

int_to_bytes(w, 54); os.write(w, 4);

Теперь начинается заголовок DIB
Указывается размер DIB заголовка, у нас он равен 40 байт.
Идентификатор занимает 4 байта.
Запишем его в файл:

int_to_bytes(w, 40); os.write(w, 4);

Далее следуют размеры изображения, по 4 байта соответственно:

int_to_bytes(w, width); os.write(w, 4);
int_to_bytes(w, height); os.write(w, 4);

Количество цветовых плоскостей. У нас одна, 2 байта:

int_to_bytes(w, 1); os.write(w, 2);

Количество бит на пиксел, у нас 32. 2 байта:

int_to_bytes(w, 32); os.write(w, 2);

Метод сжатия. У нас 0 т.е. BI_RGB - никакого сжатия нету, 4 байта:

int_to_bytes(w, 0); os.write(w, 4);

Размер сырого изображения, без заголовков. Может быть указан 0 для изображений BI_RGB - что и есть наш случай. 4 байта:

int_to_bytes(w, 0); os.write(w, 4);

Размер печати - у нас 2834 пиксел на метр по вертикали и горизонтали. По 4 байта:

int_to_bytes(w, 2834); os.write(w, 4);
int_to_bytes(w, 2834); os.write(w, 4);

Количество цветов. 0 приравнивается к 2n, где n - битность (32 бита у нас), 4 байта:

int_to_bytes(w, 0); os.write(w, 4);

Количество "важных" цветов, чаще всего игнорируется большинством приложений, может быть 0. 4 байта:

int_to_bytes(w, 0); os.write(w, 4);

А далее сама запись картинки. Необходимо заметить, что для стандарта BMP строки идут с конца изображения:

int last = height - 1;
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        os.write(bytes + (4*width*(last - i) + 4*j), 4);
    }
}

Полный код, который создает файл "file.bmp" с нарисований функцией
cos(3*x^3+5*x^2-6*x-8)

#include <fstream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define WIDTH 640
#define HEIGHT 360
 
void exit_with_msg(const char * msg)
{
    printf(msg);
    printf("\n");
    exit(1);
}
 
void int_to_bytes(char * arr, int n)
{
    for (int i = 0; i < 4; i++)
        arr[i] = (char)((n >> 8 * i) & 0xFF);
}
 
void write_bmp(const char * filename, const char * bytes, 
               int width, int height)
{
    if (width % 4 != 0) exit_with_msg("bad width");
 
    ofstream os(filename, ofstream::binary);
    char w[4]; // working array
 
    /* BMP header start */
    // BMP identifier
    w[0] = 'B'; w[1] = 'M'; os.write(w, 2);
    // file size bytes
    int_to_bytes(w, width*height*4 + 14 + 40); os.write(w, 4);
    // application dependent bytes
    int_to_bytes(w, 0); os.write(w, 4);
    //array offset
    int_to_bytes(w, 54); os.write(w, 4);
    /* BMP header end */
 
    /* DIB header start */
    // DIB size
    int_to_bytes(w, 40); os.write(w, 4);
    // width and height
    int_to_bytes(w, width); os.write(w, 4);
    int_to_bytes(w, height); os.write(w, 4);
    // color planes
    int_to_bytes(w, 1); os.write(w, 2);
    // bits per pixel
    int_to_bytes(w, 32); os.write(w, 2);
    // compression method BI_RGB (none)
    int_to_bytes(w, 0); os.write(w, 4);
    // raw image size (can be 0 for BI_RGB bitmaps)
    int_to_bytes(w, 0); os.write(w, 4);
    // image print resolution
    int_to_bytes(w, 2834); os.write(w, 4);
    int_to_bytes(w, 2834); os.write(w, 4);
    // number of colors (0 defaults to 2^n)
    int_to_bytes(w, 0); os.write(w, 4);
    // number of important colors used
    int_to_bytes(w, 0); os.write(w, 4);
    /* DIB header end */
 
    /* image start */
    int last = height - 1;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            os.write(bytes + (4*width*(last - i) + 4*j), 4);
        }
    }
    /* image end */
 
    os.close();
}
 
float f(float x)
{ return cos(3*x*x*x+5*x*x-6*x-8); }
 
int main()
{
    // allocate bytes for picutre
    char * bytes = new char[WIDTH * HEIGHT * 4];
    if (bytes == NULL) exit_with_msg("no memory");
 
    // draw picture in memory
    memset(bytes, 0, WIDTH*HEIGHT*4);
    for (float x = -5.0f; x < 5.0f; x += 0.0005f)
    {
        float y = f(x);
        int X = (int)(64*(x+5));
        int Y = (int)(90*(y+2));
        bytes[4*(WIDTH*(HEIGHT-Y) + X)] = 255;
    }
 
    // write picture to file
    write_bmp("file.bmp", bytes, WIDTH, HEIGHT);
 
    return 0;
}