将png转换为sdl的c标头

将png转换为sdl的c标头,c,sdl,header-files,C,Sdl,Header Files,我想说,我在互联网上搜索过这个话题,但它不适用于我的情况 我正在为一个使用C语言的游戏做修改,我正在编辑用于游戏的图像,但是图像需要转换为C标题才能工作。该游戏是多平台的,通过NDK为Windows和Android构建 实际上,我已经使用mbin2h完成了一些编辑工作,将“”作为解决方案的基础,它将任何二进制文件转换为适合C头的文件。它适用于Android构建,但不适用于主要的跨平台C构建 下面是一个示例代码: 这是mbin2h通常输出的内容: 0x89, 'P', 'N', 'G', 0xD,

我想说,我在互联网上搜索过这个话题,但它不适用于我的情况

我正在为一个使用C语言的游戏做修改,我正在编辑用于游戏的图像,但是图像需要转换为C标题才能工作。该游戏是多平台的,通过NDK为Windows和Android构建

实际上,我已经使用mbin2h完成了一些编辑工作,将“”作为解决方案的基础,它将任何二进制文件转换为适合C头的文件。它适用于Android构建,但不适用于主要的跨平台C构建

下面是一个示例代码:

这是mbin2h通常输出的内容:

0x89, 'P', 'N', 'G', 0xD, 0xA, 0x1A, 0xA, 0x0, 0x0, 0x0, 0xD, 'I', 'H', 'D', 'R'
以下是原始来源:

"\x89""PNG""\15\12\32\12\0\0\0\15""IHDR"
我不知道他们用什么程序把PNG转换成头文件。正如你们中的一些人指出的,它是十六进制、ASCII字符和八进制值的组合

问题是如何将png转换为类似于原始代码的头文件?为了便于其他人理解,我将原始图像、原始头和mbin2h生成的头放在zip文件中:

这实际上是针对OpenBOR的,我只想修改菜单图像,但因为我不知道如何编程,所以我需要一些帮助,很抱歉


编辑:我没有看到有回答按钮,我会把答案放上去。对不起,伙计们。

我不知道mbin2h是什么(即使我猜它是什么)。我建议您修改您的构建(例如,
Makefile
)以生成一些
image.cdata
文件,命令如下

   mbin2h image.png > image.cdata
然后有一个C文件包含(接近其开头,稍后还有一些其他函数)

然后使用
image\u数据
调用适当的例程,并且可能使用
sizeof(image\u数据)
;可能是根据类似于

 SDL_RWops * z = SDL_RWFromMem(image_data,sizeof(image_data));
当然,该代码应该与上面的
const char image\u data[]
定义(以及该定义之后)出现在同一个C文件中


注:除了@BasileStarynkevitch的答案和回复您要求“脚本”的评论外,您应该更喜欢
hextump
而不是
mbin2h
:您可以使用Posix
hextump
实用程序生成所述的include文件
image.cdata
例如。在makefile中:

image.cdata: image.png
    hexdump --format='8/1 " 0x%02x," "\n"' $< > $@
image.cdata:image.png
hexdump--格式为0x%02x,“\n”$<>$@

十六进制格式肯定不是最节省空间的格式。如果您有改进的冲动,请阅读。

将二进制数据转换为与C兼容的数据并不是那么困难,尽管我确实想知道为什么创建的结构不必要地复杂。同样,如果源代码的其余部分需要这种特定的格式,那么只需要复制原始结构并填充正确的值

。。它是十六进制、ASCII字符和八进制值的组合

这只会使源文件尽可能短。没有进一步的理由;整个图像也可以写成\x..十六进制代码,甚至小数

使头文件尽可能小是一个很好的额外挑战。除了原稿,我确保没有一行超过100个字符;尽管如此,通过使用更多的“最短备选方案”,对于测试图像,我的代码只生成1626行,而原始图像只有1921行;少18%

用法:programName input.png

它将用
.h
替换输入文件的
.png
部分,并将此输出写入当前文件夹。在OSX上工作,我想它也应该在其他类似*nix的系统上编译,因为我试图将自己限制在Posix文件I/O上。这是否包括Windows,留给“读者练习”

#包括
#包括
#包括
#包括
#包括
#定义最大线长度100
int main(int argc,字符**argv)
{
文件*f_-in,*f_-out;
字符*name_ptr,*ptr;
关蒂;
结构统计;
char out_name[文件名_MAX];
无符号字符png字节,最后一个字节八进制,输出长度;
如果(argc!=2)
{
fprintf(stderr,“这需要一个输入文件”\n);
fclose(f_in);
fclose(f_out);
返回-1;
}
f_in=fopen(argv[1],“rb”);
如果(!f_in)
{
fprintf(stderr,“这要求输入文件存在\n”);
fclose(f_in);
fclose(f_out);
返回-1;
}
if(stat(argv[1],&st))
{
fprintf(stderr,“这要求输入文件没有问题\n”);
fclose(f_in);
fclose(f_out);
返回-1;
}
name_ptr=strrchr(argv[1],“/”);//*nix路径
如果(!name_ptr)
name\u ptr=strrchr(argv[1],“\\”);//风*ws路径
如果(姓名)
name_ptr++;
其他的
name_ptr=argv[1];
如果(!*name_ptr | strlen(name_ptr)>=FILENAME_MAX)
{
fprintf(stderr,“这需要文件名的合理长度\n”);
fclose(f_in);
fclose(f_out);
返回-1;
}
strcpy(out_name,name_ptr);
ptr=输出名称;
while(*ptr)
{
*ptr=耐受力(*ptr);
ptr++;
}
ptr=strrchr(外部名称“.”);
如果(*ptr)
strcpy(ptr,“.h”);
其他的
strcat(外部名称,.h”);
f_out=fopen(out_name,“w”);
如果(!f_out)
{
fprintf(stderr,“这需要创建输出文件”\n);
fclose(f_in);
fclose(f_out);
返回-1;
}
fprintf(stderr,“正在创建%s,请稍候。\n”,out\u name);
ptr=输出名称;
while(*ptr)
{
如果(*ptr='.')*ptr='.';
ptr++;
}

对于(i=0;i我终于解决了它!正如@Basile和@5gon12eder所建议的,我在android构建中使用了类似的方法:

char openbor_menu_480x272_png[32851]={
    ...
};
我将其声明为char,并将数组大小添加到其中。
是mbin2h的输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>

#define MAX_LINE_LENGTH 100

int main (int argc, char **argv)
{
    FILE *f_in, *f_out;
    char *name_ptr,*ptr;
    off_t i;
    struct stat st;
    char out_name[FILENAME_MAX];
    unsigned char png_byte, last_byte_octal, output_length;

    if (argc != 2)
    {
        fprintf (stderr, "this requires an input file\n");
        fclose (f_in);
        fclose (f_out);
        return -1;
    }

    f_in = fopen (argv[1], "rb");
    if (!f_in)
    {
        fprintf (stderr, "this requires the input file to exist\n");
        fclose (f_in);
        fclose (f_out);
        return -1;
    }

    if (stat(argv[1], &st))
    {
        fprintf (stderr, "this requires the input file to have no problems\n");
        fclose (f_in);
        fclose (f_out);
        return -1;
    }

    name_ptr = strrchr (argv[1], '/');      // *nix path
    if (!name_ptr)
        name_ptr = strrchr (argv[1], '\\'); // Wind*ws path
    if (name_ptr)
        name_ptr++;
    else
        name_ptr = argv[1];

    if (!*name_ptr || strlen(name_ptr) >= FILENAME_MAX)
    {
        fprintf (stderr, "this requires a reasonable length for the file name\n");
        fclose (f_in);
        fclose (f_out);
        return -1;
    }
    strcpy (out_name, name_ptr);

    ptr = out_name;
    while (*ptr)
    {
        *ptr = tolower(*ptr);
        ptr++;
    }

    ptr = strrchr (out_name, '.');
    if (*ptr)
        strcpy (ptr, ".h");
    else
        strcat (out_name, ".h");

    f_out = fopen (out_name, "w");
    if (!f_out)
    {
        fprintf (stderr, "this requires the output file to be created\n");
        fclose (f_in);
        fclose (f_out);
        return -1;
    }

    fprintf (stderr, "creating %s, please hold on.\n", out_name);


    ptr = out_name;
    while (*ptr)
    {
        if (*ptr == '.') *ptr = '_';
        ptr++;
    }

    for (i=0; i<2; i++)
    {
        fprintf (f_out, "#%s", !i ? "ifndef" : "define");
        fprintf (f_out, " _");
        ptr = out_name;
        while (*ptr)
        {
            fprintf (f_out, "%c", toupper(*ptr));
            ptr++;
        }
        fprintf (f_out, "_\n");
    }

    fprintf (f_out, "\n"
        "static const struct {\n"
        "\tsize_t size;\n"
        "\tunsigned char data [%lu];\n"
        "} ", (unsigned long)st.st_size);

    ptr = name_ptr;
    while (*ptr)
    {
        if (*ptr == '.')
            fprintf (f_out, "_");
        else
            fprintf (f_out, "%c", tolower(*ptr));
        ptr++;
    }

    fprintf (f_out, " = {\n"
        "\t%lu,\n\"", (unsigned long)st.st_size);

    last_byte_octal = 0;
    output_length = 1;
    for (i=0; i<st.st_size; i++)
    {
        png_byte = fgetc (f_in);
        if (png_byte == '\\')
        {
            output_length += 2;
            if (output_length >= MAX_LINE_LENGTH)
            {
                fprintf (f_out, "\"\n\"");
                output_length = 3;
            }
            fprintf (f_out, "\\\\");
            last_byte_octal = 0;
        }
        else if (png_byte == 9)
        {
            output_length += 2;
            if (output_length >= MAX_LINE_LENGTH)
            {
                fprintf (f_out, "\"\n\"");
                output_length = 3;
            }
            fprintf (f_out, "\\t");
            last_byte_octal = 0;
        } else if (png_byte < ' ' || png_byte == '\"')
        {
            output_length += (png_byte < 8) ? 2 : 3;
            last_byte_octal = 1;
            if (output_length >= MAX_LINE_LENGTH)
            {
                fprintf (f_out, "\"\n\"");
                output_length = (png_byte < 8) ? 3 : 4;
            }
            fprintf (f_out, "\\%o", png_byte);
        } else if (png_byte > '~')
        {
            output_length += 4;
            if (output_length >= MAX_LINE_LENGTH)
            {
                fprintf (f_out, "\"\n\"");
                output_length = 5;
            }
            fprintf (f_out, "\\x%X", png_byte);
            last_byte_octal = 1;
        } else
        {
            output_length += (last_byte_octal && isxdigit(png_byte)) ? 3 : 1;
            if (output_length >= MAX_LINE_LENGTH)
            {
                fprintf (f_out, "\"\n\"");
                output_length = 2;
                last_byte_octal = 0;
            }
            if (last_byte_octal && isxdigit(png_byte))
                fprintf (f_out, "\"\"");
            fprintf (f_out, "%c", png_byte);
            last_byte_octal = 0;
        }
    }
    fprintf (f_out, "\"\n};\n\n#endif\n");

    fclose (f_in);
    fclose (f_out);

    fprintf (stderr, "done.\n");

    return 0;
}
char openbor_menu_480x272_png[32851]={
    ...
};
// Read Logo or Menu from Array.
if(!type)
    bgscreen = pngToScreen(isWide ? (void*) openbor_logo_480x272_png.data : (void*) openbor_logo_320x240_png.data);
else
    //CRxTRDude - Removed '.data' since it doesn't use it anyway.
    bgscreen = pngToScreen(isWide ? (void*) openbor_menu_480x272_png : (void*) openbor_menu_320x240_png);