【问题标题】:Converting 256 color bitmap to RGBA bitmap将 256 色位图转换为 RGBA 位图
【发布时间】:2011-12-20 21:00:00
【问题描述】:

我正在用 C++ 编写渲染器。我看到已经回答了类似的问题,我只是在寻找更多信息。我有一个 256 色位图,我将其加载到内存中,然后加载到 OpenGL 中。我无法事先转换文件,需要在内存中进行。我希望能够将其转换为 RGBA 位图以使用 Alpha 通道。有没有人有任何关于库的代码或建议可以帮助我解决这个问题?

【问题讨论】:

    标签: c++ image opengl rgb


    【解决方案1】:

    我在某处有一些代码,但只有 20 行或更少。 BMP 格式非常简单,只需读取标题,然后读取每种颜色,作为调色板数组中的索引。请记住,BMP 是颠倒的:

    //load a bmp texture, with the specified global alpha
    GLuint load_bmp8_fixed_alpha(char * FileName, Uint8 a)
    {
       int x,y,x_padding,x_size,y_size,colors_no,r,g,b,current_pallete_entry; //i unused?
       Uint8 * file_mem;
       Uint8 * file_mem_start;
       Uint8 * texture_mem;
       Uint8 * read_buffer;
       Uint8 * color_pallete;
       FILE *f = NULL;
       GLuint texture;
    
         f = fopen (FileName, "rb");
         if (!f) return 0;
         file_mem = (Uint8 *) calloc ( 20000, sizeof(Uint8));
         file_mem_start=file_mem;
         fread (file_mem, 1, 50, f);//header only
         //now, check to see if our bmp file is indeed a bmp file, and if it is 8 bits, uncompressed
         if(*((short *) file_mem)!=19778)//BM (the identifier)
           {
               free(file_mem_start);
               fclose (f);
               return 0;
           }
       file_mem+=18;
       x_size=*((int *) file_mem);
       file_mem+=4;
       y_size=*((int *) file_mem);
       file_mem+=6;
       if(*((short *)file_mem)!=8)//8 bit/pixel?
           {
               free(file_mem_start);
               fclose (f);
               return 0;
           }
    
       file_mem+=2;
       if(*((int *)file_mem)!=0)//any compression?
           {
               free(file_mem_start);
               fclose (f);
               return 0;
           }
       file_mem+=16;
    
       colors_no=*((int *)file_mem);
       if(!colors_no)colors_no=256;
       file_mem+=8;//here comes the pallete
    
       color_pallete=file_mem+4;
       fread (file_mem, 1, colors_no*4+4, f);//header only
       file_mem+=colors_no*4;
    
       x_padding=x_size%4;
       if(x_padding)x_padding=4-x_padding;
    
       //now, allocate the memory for the file
       texture_mem = (Uint8 *) calloc ( x_size*y_size*4, sizeof(Uint8));
       read_buffer = (Uint8 *) calloc ( 2000, sizeof(Uint8));
    
    
       for(y=0;y<y_size;y++)
           {
               //fread (texture_mem+y*x_size, 1, x_size-x_padding, f);
               fread (read_buffer, 1, x_size-x_padding, f);
    
               for(x=0;x<x_size;x++)
                   {
                       current_pallete_entry=*(read_buffer+x);
                       b=*(color_pallete+current_pallete_entry*4);
                       g=*(color_pallete+current_pallete_entry*4+1);
                       r=*(color_pallete+current_pallete_entry*4+2);
                       *(texture_mem+(y*x_size+x)*4)=r;
                       *(texture_mem+(y*x_size+x)*4+1)=g;
                       *(texture_mem+(y*x_size+x)*4+2)=b;
                       *(texture_mem+(y*x_size+x)*4+3)=a;
                   }
    
           }
    
       free(file_mem_start);
       free(read_buffer);
       fclose (f);
       //ok, now, hopefully, the file is loaded and converted...
       //so, assign the texture, and such
    
       glGenTextures(1, &texture);
       glBindTexture(GL_TEXTURE_2D, texture);    //failsafe
       bind_texture_id(texture);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
       if(poor_man)
           {
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
           }
       else if(use_mipmaps)
           {
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
               glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
           }
       else
           {
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
           }
    
       if(have_arb_compression)
           {
               if(have_s3_compression)
               glTexImage2D(GL_TEXTURE_2D,0,COMPRESSED_RGBA_S3TC_DXT5_EXT,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem);
               else
               glTexImage2D(GL_TEXTURE_2D,0,COMPRESSED_RGBA_ARB,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem);
    
           }
       else
       glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,x_size, y_size,0,GL_RGBA,GL_UNSIGNED_BYTE,texture_mem);
    
       check_gl_errors();
       free(texture_mem);
       return texture;
    }
    

    【讨论】:

    • 这 20 行现在非常有用。只是想知道如何做以及 256 色位图有何不同。
    • 给我你的邮箱,我发给你。
    • 我的邮箱是 redpixelengineer@gmail.com
    【解决方案2】:

    您可以使用most of these libraries 来执行此操作(并且您可以使用任意数量的其他格式)。我建议使用非官方的 OpenGL SDK。但话又说回来,我写了它,所以把它当作它的价值;)

    我希望能够将其转换为 RGBA 位图以使用 Alpha 通道。

    这将是相当困难的,因为 BMP 格式实际上没有 Alpha 通道。我们说的是 BMP 格式的图像,是吗?

    【讨论】:

    • 我的印象是可能有 RGBA 位图。如果不是,那么我想将其转换为任何具有红色、绿色、蓝色和 alpha 分量并且与 OpenGL 兼容的格式。谢谢尼科尔。你一直是这个网站上最牛的程序员之一。
    • 8b BMP 没有 Alpha 通道。但根据您的需要,您可以根据图像对比度设置 alpha。或者,您可以使用带有 alpha 的单独 BMP。虽然我建议尽可能使用 DDS 格式。
    • @PladniusBrooks:如果您指的是 BMP 格式的图像,请不要再称它们为“位图”。术语“位图”是光栅图像的通用术语;它并不总是意味着 .bmp 文件。此外,OpenGL 不读取图像格式。由用户代码将它们变成“与 OpenGL 兼容”的东西;这就是我指出的图书馆所做的。您的工作应该是生成具有您需要的颜色通道并且可以由这些库之一加载的图像。与大多数其他格式一样,TGA 图像可以具有 Alpha 通道。
    猜你喜欢
    • 2014-03-17
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 2023-03-17
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多