Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [С++] Запись bmp в массив, Получить матрицу яркости 
:(
    Опции темы
b26041986
Дата 28.3.2016, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.2.2016

Репутация: нет
Всего: нет



Помогите, пожалуйста! Как на С++ можно считать монохромный bmp файл в массив? (Нужно получить матрицу яркости. Т.е. должен получится двумерный int массив из элементов 0...255).

Это сообщение отредактировал(а) b26041986 - 28.3.2016, 01:31
PM MAIL   Вверх
math64
Дата 28.3.2016, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



В какой среде программируешь? Если нужна универсальная программа - разбирайся с форматом бмп.
Иначе - используй функции среды для загрузки изображения (обычно она универсальная, и подходит под любой формат) и получения отдельных пикселей (обычно получаешь 32 разрядное число, байты которого прозрачность, красный, зеленый и синий комоненты - для монохромного изображения цветовые компоненты будут одинаковыми).
PM   Вверх
rudolfninja
Дата 28.3.2016, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Я когда-то писал диссертацию на тему стеганографии, и был у меня там кусок кода, который, насколько я понял, делал то, что вам требуется.
Вот код, правда, это один из чернвых вариантов, но вроде работает:
Bmp.h (вам отсюда нужны структуры и метод readFromFile)
Код

#ifndef BMP_H
#define BMP_H

typedef unsigned char uchar;
typedef unsigned int  uint;

typedef struct RGBApixel {
    uchar Blue;
    uchar Green;
    uchar Red;
    uchar Alpha;
} RGBApixel;

#pragma pack(push,1)

typedef struct BMPH {
    short bfType;
    uint  bfSize;
    short bfReserved1;
    short bfReserved2;
    uint  bfOffBits;

    uint  biSize;
    uint  biWidth;
    uint  biHeight;
    short biPlanes;
    short biBitCount;
    uint  biCompression;
    uint  biSizeImage;
    uint  biXPelsPerMeter;
    uint  biYPelsPerMeter;
    uint  biClrUsed;
    uint  biClrImportant;
} BMPH;

#pragma pack(pop)

class BMP
{
public:
    RGBApixel** pixels;
    BMPH header;

    BMP();
    ~BMP();
    bool readFromFile(char* filename);
    bool writeToFile(char* filename);
    RGBApixel getPixel(int x, int y);
    void setPixel(int x, int y, RGBApixel pixel);
    BMP operator=(BMP copy);
};

#endif // BMP_H

Реализация readFromFile
Код

bool BMP::readFromFile(char *filename)
{
    using namespace std;

    short bitCount;
    int width;
    int height;
    int colSize;

    char* buffer;

    ifstream input(filename, ios::in | ios::binary);
    input.read((char*) &(this->header), 54);
    input.seekg(this->header.bfOffBits, ios_base::beg);

    bitCount = this->header.biBitCount;
    width = this->header.biWidth;
    height = this->header.biHeight;

    colSize = (int)((width*bitCount)/8.0);

    while (8*colSize < width*bitCount) {
        colSize++;
    }

    while (colSize % 4) {
        colSize++;
    }

    this->pixels = new RGBApixel*[width];
    buffer = new char[colSize];
    for (int i = 0; i < width; i++)
        this->pixels[i] = new RGBApixel[height];

    for (int i = height-1; i >= 0; i--) {
        input.read(buffer, colSize);
        for (int j = 0; j < width; j++) {
            if (bitCount == 24) {
                memcpy((char*) &(pixels[j][i]), buffer + 3*j, 3);
            } else if (bitCount == 32) {
                memcpy((char*) &(pixels[j][i]), buffer + 4*j, 4);
            } else {
                return false;
            }
        }
    }
    return true;
}

Код несложный, попробуйте разобраться.
PM MAIL Skype   Вверх
math64
Дата 28.3.2016, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Пример не учитывает возможности что пиксель может заниметь 1 байт (что логично для монохромного бмп)
PM   Вверх
b26041986
Дата 28.3.2016, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.2.2016

Репутация: нет
Всего: нет



Использую Dev-Cpp.

появляется ошибка в строке  


ifstream input(filename, ios::in | ios::binary);


Сообщение:
`std::ifstream input' has initializer but incomplete type 

пока еще буду разбираться ...

.....
м.б. для такого задания лучше использовать среду по-крупнее?

PM MAIL   Вверх
math64
Дата 29.3.2016, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Имелось в в виду WinAPI. MFC, Qt и т. д. - у них у всех есть свои методы для работы с изображениями (хотя для Windows всё в итоге сводится к WinAPI).
Вместо ifstream можно использовать <strdio.h>: FILE* input = fopen(filename, "rb"); если тебе это привычнее. Но тогда далее тоже следует использовать stdio.
Учти:
в 16-разрядной ОС: short - 16, int - 16, long - 32 бит
в 32-разрядной ОС: short - 16, int - 32, long - 32 бит
в 64-разрядной ОС: short - 16, int - 32, long - 64 бит
Для какой разрядности код  rudolfninja и правильно ли там определено uint ?

PM   Вверх
rudolfninja
Дата 29.3.2016, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



В 32-разрядной и в 64-разрядной ОС, насколько я понимаю, размер uint будет одинаковый.

Цитата(math64 @  29.3.2016,  08:15 Найти цитируемый пост)
правильно ли там определено uint

А почему нет?
PM MAIL Skype   Вверх
math64
Дата 29.3.2016, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



rudolfninja, если бы ты написал typedef unsigned int  uint32; - было бы понятно, какую ты хочешь разрядность.

разрядность фундаментальных типов в C++
т.е. при переходе WIN32->WIN64 поменяется только разрядность указателей.
но в 64-разрядном Линуксе long будет 64 разрядный.

PM   Вверх
Hate42
Дата 30.3.2016, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.2.2016

Репутация: нет
Всего: нет



Спасибо

Это сообщение отредактировал(а) Hate42 - 2.4.2016, 03:07
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0514 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.