C ++:读错了位图 [英] C++: Read bitmap wrong

查看:127
本文介绍了C ++:读错了位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想读 .BMP 使用C ++文件并保存灰度值的Ubuntu 14.04下归到一个载体(平均超过RGB值)。不知怎的,矢量值最终完全错误的。你能想象,为什么?

I'm trying to read a .bmp file with c++ and save the grey values (average over RGB values) normalized into a vector under Ubuntu 14.04. Somehow the values of the vector end up completely wrong. Can you imagine why?

std::vector<double> readBMP(const char* filename, int* width, int* height){
    std::vector<double> bmp;
    FILE* f = fopen(filename, "rb");

    if(f == NULL){
        std::cerr << "file not found!" << std::endl;
        std::vector<double> empty;
        width = NULL;
        height = NULL;
        return empty;
    }

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

    // extract image height and width from header
    *width = *(int*)&info[18];
   *height = *(int*)&info[22];
    int data_offset = *(int*)(&info[0x0A]);
    fseek(f, (long int)(data_offset - 54), SEEK_CUR);

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

    for(int i = 0; i < *height; i++)
    {
        fread(data, sizeof(unsigned char), row_padded, f);
        for(int j = 0; j < *width*3; j += 3)
        {
            // Convert (B, G, R) to (R, G, B)
            tmp = data[j];
            data[j] = data[j+2];
            data[j+2] = tmp;
            bmp.push_back(((double)data[j]+(double)data[j+1]+(double)data[j+2])/(3*255));

            std::cout << "R: "<< (int)data[j] << " G: " << (int)data[j+1]<< " B: " << (int)data[j+2]<< std::endl;
        }
    }
    return bmp;
}

我打印的RGB值,并用一个例子形象,其中有四个像素检查了它:

I print the rgb values, and checked it with an example image, which has four pixels:

black | black | black
---------------------
grey  | grey  | grey
---------------------
white | white | white

预期的输出应(它的反向):

The expected output should be (it's reversed):

R: 255 G: 255 B: 255
R: 255 G: 255 B: 255
R: 255 G: 255 B: 255
R: 128 G: 128 B: 128
R: 128 G: 128 B: 128
R: 128 G: 128 B: 128
R: 0 G: 0 B: 0
R: 0 G: 0 B: 0
R: 0 G: 0 B: 0

,但它是:

R: 255 G: 255 B: 255
R: 255 G: 255 B: 255
R: 255 G: 255 B: 255
R: 128 G: 128 B: 255
R: 128 G: 255 B: 128
R: 255 G: 128 B: 128
R: 0 G: 0 B: 255
R: 0 G: 255 B: 0
R: 255 G: 0 B: 0

注意:
的code是这个问题的一个答案的修改版本:
读取bmp文件像素值

推荐答案

最后,我得到了我的code正确,以防有人绊倒在这个问题:我的错误是,该图像是ABGR,我以为BGR。

Finally I got my code right, in case someone stumbles upon this question: My mistake was, that the image was in ABGR, I assumed BGR.

#include <cstdio>
#include <iostream>
#include <vector>

std::vector<double> readBMP(const char* filename, int* width, int* height){
    std::vector<double> bmp;
    FILE* f = fopen(filename, "rb");

    if(f == NULL){
        std::cerr << "file not found!" << std::endl;
        std::vector<double> empty;
        width = NULL;
        height = NULL;
        return empty;
    }

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

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

    int data_offset = *(int*)(&info[0x0A]);
    if(data_offset > 0)
        fseek(f, (long int)(data_offset - 53), SEEK_CUR);

    std::cout << "  Name: " << filename << std::endl;
    std::cout << " Width: " << *width << std::endl;
    std::cout << "Height: " << *height << std::endl;
    std::cout << "Offset: " << data_offset << std::endl;

    int row_padded = (*width*4 + 4) & (~4);
    unsigned char* data = new unsigned char[row_padded];
    //unsigned char tmp;

    for(int i = 0; i < *height; i++){
        fread(data, sizeof(unsigned char), row_padded, f);
        for(int j = 0; j < row_padded; j += 4)
        {
            // Convert (B, G, R) to (R, G, B)
            //tmp = data[j];
            //data[j] = data[j+2];
            //data[j+2] = tmp;
            bmp.push_back(((double)data[j+2]+(double)data[j+1]+(double)data[j+2])/(3*255));

            //std::cout << "R: "<< (int)data[j+1] << " G: " << (int)data[j+2]<< " B: " << (int)data[j+3]<< std::endl;
        }
    }
    free(data);

    //reverse order of the vector
    std::vector<double>bmp_final;
    std::cout << bmp.size() << std::endl;
    for(int i=*height-1; i>=0; --i){
        for(int j=0; j<*width; ++j){
            bmp_final.push_back(bmp.at(*width*i+j));
        }
    }

    return bmp_final;
}

感谢大家的帮助!

Thanks to everyone for the help!

这篇关于C ++:读错了位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆