C++ 如何更改、修改、剪切和交换位图中的像素

C++ 如何更改、修改、剪切和交换位图中的像素,c++,opengl,image-manipulation,C++,Opengl,Image Manipulation,我想修改位图: 更改(交换)像素位置(用于以后的鱼眼校正) 在子位图中分割位图(例如,从1个位图中生成4个位图)(用于以后不同GL_四边形的纹理化) 为此,我需要的代码如何修改位图的像素 下面的代码示例工作并从文件创建纹理: HBITMAP hbpInput = (HBITMAP)::LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); BITMAP bmpOutput;

我想修改位图:

  • 更改(交换)像素位置(用于以后的鱼眼校正)

  • 在子位图中分割位图(例如,从1个位图中生成4个位图)(用于以后不同GL_四边形的纹理化)

为此,我需要的代码如何修改位图的像素

下面的代码示例工作并从文件创建纹理:

HBITMAP hbpInput = (HBITMAP)::LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

BITMAP bmpOutput;
::GetObject (hbpInput, sizeof (bmpOutput), &bmpOutput);

(...)

glTexImage2D(GL_TEXTURE_2D, 0, 3, bmpOutput.bmWidth, bmpOutput.bmHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bmpOutput.bmBits);
获取位数组需要哪些代码

我已经尝试过GetDIBits(),但正如您肯定知道的那样,这对für IMAGE(struct)不起作用:)

有什么具体的想法可以改变像素的位置吗


多谢各位

由于位图是如此简单的文件,您只需读取标题并构建像素数组/向量,然后进行编辑即可

这是我很久以前写的一个函数,虽然它充满了一些不好的编码习惯

m_imagefile是一个基本结构,其中包含重要的图像信息,如宽度、高度、bpp、格式和原始字节数组

m_imagefile *loadBMP(char *Filename) {
    FILE        *BMPFile=NULL;
    errno_t     error;
    m_imagefile *IMG=NULL;

    error=fopen_s(&BMPFile, Filename, "rb");
    if(error!=0) {
        return NULL;
    }

    IMG=new m_imagefile;

    GLshort magic=0;

    fseek(BMPFile, 0x00, SEEK_SET);
    fread(&magic, sizeof(GLshort), 1, BMPFile);
    fseek(BMPFile, 0x12, SEEK_SET);
    fread(&IMG->width, sizeof(GLint), 1, BMPFile);
    fseek(BMPFile, 0x16, SEEK_SET);
    fread(&IMG->height, sizeof(GLint), 1, BMPFile);
    fseek(BMPFile, 0x1C, SEEK_SET);
    fread(&IMG->bpp, sizeof(GLshort), 1, BMPFile);

    //First 2 bytes should be 0x424d or "BM" in ASCII
    if(IMG->width == 0 || IMG->height == 0 || !(magic & 0x424D)) {
        fclose(BMPFile);
        delete IMG;
        return NULL;
    }

    //Bitmaps are stored as BGR, not RGB
    if(IMG->bpp==24) {
        IMG->format = GL_BGR_EXT;
    } else if(IMG->bpp==32) {
        IMG->format = GL_BGRA_EXT;
    } else {
        fclose(BMPFile);
        delete IMG;
        return NULL;
    }

    IMG->data=new GLubyte[IMG->height*IMG->width*IMG->bpp/8];
    fseek(BMPFile, 54, SEEK_SET);
    fread(IMG->data, sizeof(GLbyte), IMG->height*IMG->width*IMG->bpp/8, BMPFile);

    fclose(BMPFile);

    return IMG;
 }

以下调用中的最后一个参数是像素的字节数组:

glTexImage2D(GL_TEXTURE_2D, 0, 3, bmpOutput.bmWidth, bmpOutput.bmHeight,
             0, GL_RGB, GL_UNSIGNED_BYTE, bmpOutput.bmBits);
这意味着
bmpOutput.bmBits
指向包含以下字节数的数组中的第一个字节:

3 * bmpOutput.bmWidth * bmpOutput.bmHeight
这意味着每像素3个字节(红、绿、蓝各一个字节)


说到这里,基于你的问题,听起来你真正想要的是能够将纹理的不同部分映射到不同的四边形上。为此,您可以使用。只使用一个纹理对象,但调整每个四边形的纹理坐标以映射到纹理图像的不同部分。

@Shezan Baig@Murka感谢您的提示。为了使用本机函数,我将格式从位图更改为CImage。使用CImage和您的答案,很容易为der rgba值创建数组。