如何将argb像素阵列变成SDL表面?

时间:2018-07-26 17:24:00

标签: c sdl sdl-2

使用C和SDL2,我有一个具有ARGB8888格式的像素阵列。

Uint32 *pixels = (Uint32 *) malloc (sizeof(Uint32)*(Uint32)windowWidth*(Uint32)windowHeight);

我想将所有像素信息放入一个新的SDL_Surface中,准备另存为.bmp。我该怎么做?

我不确定,因为新表面具有RGBA8888格式,并且sdl转换功能需要将现有表面转换为新表面。而且没有简单地将所有像素数组值传递到表面的函数,因此我知道它将涉及某种循环,该循环将像素一一分配。

1 个答案:

答案 0 :(得分:0)

您可以手动将位图位保存到文件中。位图文件通常不超过24位,并且位图查看器倾向于忽略alpha。以下代码假定bits是32位像素。如果需要24位格式,则必须将输入从ARGB转换为RGB,并且还必须考虑填充。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#pragma pack(push, 1)
typedef struct my_BITMAPFILEHEADER {
    uint16_t bfType;
    uint32_t bfSize;
    uint16_t bfReserved1;
    uint16_t bfReserved2;
    uint32_t bfOffBits;
}my_BITMAPFILEHEADER;

typedef struct my_BITMAPINFOHEADER {
    uint32_t biSize;
    int32_t  biWidth;
    int32_t  biHeight;
    uint16_t biPlanes;
    uint16_t biBitCount;
    uint32_t biCompression;
    uint32_t biSizeImage;
    int32_t  biXPelsPerMeter;
    int32_t  biYPelsPerMeter;
    uint32_t biClrUsed;
    uint32_t biClrImportant;
}my_BITMAPINFOHEADER;
#pragma pack(pop)

int copy(uint8_t* bits, int width, int height, int bitcount)
{
    //compiler test:
    if(sizeof(my_BITMAPFILEHEADER) != 14 && sizeof(my_BITMAPINFOHEADER) != 40)
    {
        printf("bitmap structures not packed properly\n");
        return 0;
    }

    //width_in_bytes is roughly w * bytes_per_pixel, it takes padding in to account
    int width_in_bytes = ((width * bitcount + 31) / 32) * 4;    
    uint32_t imagesize = width_in_bytes * height;   
    my_BITMAPFILEHEADER filehdr = { 0 };
    my_BITMAPINFOHEADER infohdr = { 0 };
    memcpy(&filehdr, "BM", 2);
    filehdr.bfSize = 54 + imagesize;
    filehdr.bfOffBits = 54;
    infohdr.biSize = 40; 
    infohdr.biPlanes = 1;
    infohdr.biWidth = width;
    infohdr.biHeight = height;
    infohdr.biBitCount = bitcount;
    infohdr.biSizeImage = imagesize;

    FILE *fout = fopen("test.bmp", "wb");
    fwrite(&filehdr, sizeof(filehdr), 1, fout);
    fwrite(&infohdr, sizeof(infohdr), 1, fout);
    fwrite((char*)bits, 1, imagesize, fout);
    fclose(fout);

    return 1;
}

用法:

copy(bits, width, height, 32);
//or
copy(bits, width, height, 24);