将png转换为sdl的c标头
我想说,我在互联网上搜索过这个话题,但它不适用于我的情况 我正在为一个使用C语言的游戏做修改,我正在编辑用于游戏的图像,但是图像需要转换为C标题才能工作。该游戏是多平台的,通过NDK为Windows和Android构建 实际上,我已经使用mbin2h完成了一些编辑工作,将“”作为解决方案的基础,它将任何二进制文件转换为适合C头的文件。它适用于Android构建,但不适用于主要的跨平台C构建 下面是一个示例代码: 这是mbin2h通常输出的内容:将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,
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
:您可以使用Posixhextump
实用程序生成所述的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);