2012-06-15 6 views
1

Мне удалось считывать значения пикселей из 24-разрядного 512x512 .bmp в трехмерный массив. Ниже приведен код, который имеет для тестового изображения lena512.bmp.Преобразование трехмерных элементов массива из шестнадцатеричного в двоичный для bmp

...snip ... 
FILE *fptr; 

int i, j, k; 
char *filename = "lena512.bmp"; 
//char *filename2 = "anotherimage.bmp"; 
//ofstream myfile; 
unsigned char databuff[512][512][3]; 


BmpFileHeader fheader; 
BmpInfoHeader iheader; 

printf("sizeof: fheader: %d iheader: %d\n\n", sizeof(fheader), 
     sizeof(iheader)); 
if ((sizeof(fheader) != 14) || (sizeof(iheader) != 40)) { 
    printf("Header structs are not properly packed\n"); 
    return 0; 
} 

if ((fptr = fopen(filename, "r")) == NULL) { 
    printf("Coulsn't open file %s for reading.\n", filename); 
    return 1; 
}; 
if (fread(&fheader, sizeof(fheader), 1, fptr) != 1) { 
    printf("Couldn't read fheader.\n"); 
    return 0; 
} 
if (fread(&iheader, sizeof(iheader), 1, fptr) != 1) { 
    printf("Couldn't read iheader.\n"); 
    return 0; 
} 
printf("   fheader.type = %04x \n", fheader.type); 
printf("   fheader.size = %u \n", fheader.size); 
printf("  fheader.reserved1 = %u \n", fheader.reserved1); 
printf("  fheader.reserved2 = %u \n", fheader.reserved2); 
printf("   fheader.offset = %u \n", fheader.offset); 
printf("   iheader.size = %u \n", iheader.size); 
printf("   iheader.width = %u \n", iheader.width); 
printf("   iheader.height = %u \n", iheader.height); 
printf("   iheader.planes = %u \n", iheader.planes); 
printf("   iheader.bits = %u \n", iheader.bits); 
printf(" iheader.compression = %u \n", iheader.compression); 
printf("  iheader.imagesize = %u \n", iheader.imagesize); 
printf(" iheader.xresolution = %u \n", iheader.xresolution); 
printf(" iheader.yresolution = %u \n", iheader.yresolution); 
printf("  iheader.ncolors = %u \n", iheader.ncolors); 
printf("iheader.importantcolors = %u \n", iheader.importantcolors); 
printf("\n"); 


if ((iheader.height != 512) || (iheader.width != 512) || (iheader.bits != 24)) { 
    printf("This only works for 512x512 24-color bitmaps\n"); 
    return 0; 
} 
if (fheader.offset != 54) { 
    printf("This only works if the offset is equal to 54\n"); 
    return 0; 
} 

for (i = 0; i < iheader.height; i++) { 
    for (j = 0; j < iheader.width; j++) { 
     if (fread(&databuff[i][j][0], 3, 1, fptr) != 1) { 
      printf("Couldn't read colors for element [%d][%d]\n", i, j); 
      return 0; 
     } 
    } 
} 
//myfile.open("lena512bmp_24bit.txt"); 
for (i = 0; i < 1; i++) { /* This should only give you the first row */ 
    printf("Row %2d:\n", i); 
    for (j = 0; j < 1; j++) { /* look at the first element on each row */ 
     printf(" "); 
     for (k = 0; k < 3; k++) { 
    printf("%02x ", databuff[i][j][k]); 
    cout << databuff[i][j][k]; 

     } 
     printf("\n"); 
    } 
    printf("\n\n"); 
} 
//myfile.close(); 
fclose(fptr); 
return 0; 

Я также включать в себя заголовок под названием bmp_headers.h к этому филе, которая не является достаточно актуальным на вопрос, что я хотел спросить.
Результат здесь 37 51 9E (отображается в шестнадцатеричном формате), так как мои петли for просто рассматривают первые 3 элемента первой строки (после первых 54 байтов заголовков изображений). Вывод изображения 512x512 соответствует значениям, отображаемым в шестнадцатеричном редакторе для одного и того же изображения. Я хочу преобразовать каждый элемент в этот массив в строку двоичных символов и отобразить их. (т.е. 37 51 9E ==>00110111 01010001 10011110).
Если я правильно понял, мне пришлось бы преобразовать этот массив в строку, а затем в шестнадцатеричный, а затем в строку двоичного кода. Есть ли более простой способ сделать это? Сейчас я немного запутался. Любая помощь будет оценена по достоинству.

+0

Почему 3-D массив? O_o –

+0

@EitanT: Цветные плоскости? –

+0

3 байта для битовой глубины: RGB –

ответ

0

Ну, вопрос, помечено C++, так вот, как это сделать в C++:

#include <sstream> 

template <typename T> 
std::string ToBinary(T value) 
{ 
    std::stringstream sstream; 
    while (value > 0) 
    { 
     sstream << static_cast<char>((value % 2) + 48); 
     value /= 2; 
    } 
    std::string result = sstream.str(); 
    std::reverse(result.begin(), result.end()); 
    return result; 
} 

for (i = 0; i < 1; i++) { /* This should only give you the first row */ 
    std::cout << "Row " << i << std::endl; 
    for (j = 0; j < 1; j++) { /* look at the first element on each row */ 
     std::cout << " "; 
     for (k = 0; k < 3; k++) { 
      std::cout << ToBinary(databuff[i][j][k]); 
     } 
     std::cout << std::endl; 
    } 
    std::cout << std::endl; 
}