Алгоритм — C ++ Лучший способ прочитать BitMap & quot; Правильный путь вверх & quot; в 1D Вектор

Я пытаюсь прочитать BitMap «Правильный путь вверх» в одномерный вектор. Вот моя первая попытка. Это довольно неуклюже

void BitMap::ReadBMP(const char* filename)
{
FILE* f = fopen(filename, "rb");
if(f == NULL)
throw "Argument Exception";

unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

// extract image height and width from header
m_width = *(int*)&info[18];
m_height = *(int*)&info[22];

cout << endl;
cout << "  Name: " << filename << endl;
cout << " Width: " << m_width << endl;
cout << "Height: " << m_height << endl;

int row_padded = (m_width*3 + 3) & (~3);
unsigned char* data = new unsigned char[row_padded];
unsigned char tmp;

std::deque<Element> mydeque;
std::vector<Element> bmpRow;

for(int i = 0; i < m_height; i++)
{
fread(data, sizeof(unsigned char), row_padded, f);
for(int j = 0; j < m_width*3; j += 3)
{
// BGRA format
Element element;
element.Elements[0] = data[j+2];
element.Elements[1] = data[j+1];
element.Elements[2] = data[j];
element.Elements[3] = 0; // for alpha
bmpRow.push_back(element);
}
mydeque.insert (mydeque.begin(),bmpRow.begin(),bmpRow.end());
bmpRow.clear();
}

std::copy(mydeque.begin(), mydeque.end(), std::back_inserter(m_pixelVec));
cout<< "After Deque Copy" << endl;

fclose(f);
delete data;

}

Проблема в том, что мне нужно перебирать данные в другой точке приложения, как это — обратите внимание, что h и W поменялись местами для setPixel. Пожалуйста, не обращайте внимания на эту часть, это просто для того, чтобы продемонстрировать, что BitMap необходимо повернуть в части C ++ выше:

for (int h = 0; h<imageHeight; h++)
{
for (int w = 0; w<imageWidth; w++)
{
int p = 0;
Pixel pixel = currentImagePixelVec.get(pixelVecLoc);
p = (pixel.Alpha<<24) | (pixel.Red<<16) | (pixel.Green<<8) | pixel.Blue;
imageData.setPixel(w, h, p);
pixelVecLoc++;
}
}

Так что я хотел бы повернуть BitMap, как я читал его в 1D Vector. Можете ли вы предложить хороший способ?

РЕДАКТИРОВАТЬ:
Это действительно только для целей тестирования. Я использую только BitMaps, я знаю высоту и ширину и т. Д. Я хотел бы знать с точки зрения алгоритма, как люди будут это делать

0

Решение

Насколько я понимаю, вы хотите транспонировать данные изображения; хранить столбцы пикселей в смежных сегментах m_pixelVec, а не в строках.

Мне кажется, что самый простой способ сделать это — поместить значения в 2D-структуру данных по мере их чтения, а затем сгладить их. Это делает тривиальным изменение порядка главной колонки по сравнению с основной строкой, просто переворачивая индексы.

Чтобы получить доступ к любой точке, когда я хочу, без каких-либо push_backs, я предварительно выделил все, что предполагает, что тип Element является конструируемым по умолчанию. Я использовал вектор векторов, но 2D-массив мог бы работать так же хорошо.

Я заметил, что вы поместили первую строку read (i == 0) в конце вашего вектора и предположили, что хотите сохранить это поведение. Отсюда и индекс m_height-i-1 при назначении bmpcolrow,
Другая возможность состоит в том, чтобы просто использовать bmpcolrow[j][i] и затем поверните столбцы при вставке (используйте col.rbegin() а также col.rend() в последней строке).

std::vector<std::vector<Element>> bmpcolrow(m_width, std::vector<Element>(m_height));

for(int i = 0; i < m_height; i++) {
fread(data, sizeof(unsigned char), row_padded, f);
for(int j = 0; j < m_width; j++) {
// BGRA format
Element element;
element.Elements[0] = data[3*j+2];
element.Elements[1] = data[3*j+1];
element.Elements[2] = data[3*j];
element.Elements[3] = 0; // for alpha
bmpcolrow[j][m_height-i-1] = element;
}
}

for (const auto& col : bmpcolrow)
m_pixelVec.insert(m_pixelVec.end(), col.begin(), col.end());
1

Другие решения

Других решений пока нет …