读取脚本数据失败字库失败退出脚本怎么办

[利用 Python 快速制作游戏字库](一)基础篇+分割字库图片
阅读:500次&&&时间: 00:05:52&&
原始出处: Your life just a MOD
其实早就打算写相关文章的,但因为抽不出时间还是一直没动笔。最近又想起来,然后翻开近半年前的草稿一看,居然一字未动。现在回想起来,当初定的目标似乎太遥远了,所以我打算把原来准备一次写完的内容拆成一小段一小段来写。这样有空就写一小段,似乎更实际一点。
在开始读这篇心得前,本人假定你对Python语言已有足够的了解,并已能写一些小程序;清楚游戏字库特别是图片类字库的原理、构造、作用,已做过或有充分准备可以制作一种字库。对于文章中出现的一些库和模块的功能,我会进行一定程度的讲解,更多需要你自行查阅。
1、你需要***python 2.7.x(目前我使用2.7.2),可以在这里找到:http://python.org/getit/
2、***PIL(python的一个第三方图像处理库),当前最新版是1.1.7,点此下载,最新版本在此查看:/products/pil/
3、NVIDIA Texture Tools,可以将其他格式图片转换为dds格式,而且效率较高,还支持很多选项。但不单独提供,这是我提取出来的版本。点此下载
4、[可选]本人制作的字库生成器,你也可以使用其他类似软件代替,但本篇中提到字库生成器都以此为准。点此下载
5、urfFontReader(Urf字库生成器字体读取脚本)。很多例子都会用到,点此下载(记得点download)
转换bmp至png格式
字库生成的方法参考字库生成器的文章,这里不再详述。
由于字库生成器生成的bmp图片不方便接下来的操作,而且文件相对较大,所以推荐转换为png格式保存。png格式可以包含透明层,体积也很小,而且读取速度不慢。假设生成的图片为&1.bmp&,然后看下面的代码:&&
import Image #导入PIL的基本处理模块
#打开bmp文件并转换为RGBA模式
bmp = Image.open('1.bmp').convert('RGBA')
#用一个列表保存像素数据
#将所有像素用简单公式转换为灰度作为透明层,底图使用白色
for pix in bmp.getdata():
&&& rgba.append((255, 255 ,255 ,int( pix[0]*0.299 + pix[1]*0.587 + pix[2]*0.114 )))
bmp.putdata(rgba)
bmp.save('1.png')
以上代码可以稍加修改,然后将此脚本作为一个命令行工具使用。
读取字体数据
我提供的urfFontReader可以很方便的读出保存在bin文件中的字体信息。这样就可以将相关数据转换为游戏需要的格式。下面通过分析该脚本的代码,初步了解二进制数据的处理方法。
#从struct模块引入必要函数
from struct import pack,unpack
def ReadUrfFontInfo(fontname):
&&& #以二进制模式打开文件并读取
&&& fl=open(fontname+'.bin','rb')
&&& #解开文件头中的数据
&&& img_w,img_h,nums,ch,stp1,stp2=unpack('6i',fl.read(24))
&&& #解开所有字符数据
&&& data = unpack('='+'H4i'*nums,fl.read(-1)) #+&='使之采用标准数据大小
&&& #用一个字典保存字符数据,方便使用
&&& #转换成字典
&&& for i in xrange(nums):
&&&&&&& c,w,h,x,y = data[i*5:i*5+5]
&&&&&&& db[c]=(w,h,x,y)
&&& #返回数据
&&& return (img_w,img_h,nums,ch),db
&整个脚本主要使用了struct模块的upack函数来解构二进制数据。因为python并不能直接处理二进制数据(虽然可以当作字符串来处理,当其他数据类型就另当别论了)。upack函数的第一个参数用来描述数据结构,第二个参数是以字符串形式保存的数据。因为我这个字库当初设计得很简单,所以只用到二中类型,分别是:&H&无符号短整数;&i&有符号整数。与C程序中相应类型对应。
关于struct模块的更详细信息可以在网上搜索相关例程,或者在python控制台用help函数查看内部文档,之后不再详述。
下面是一个从其他脚本调用urfFontReader的实例。
#直接导入所需函数
from urfFontReader import ReadUrfFontInfo
#使用该函数读取字体bin文件,返回值分别存入等号前的变量
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r'mydirmyfont')
#打印图片的宽、高,包含的字符数和字符默认高度
print &&&image : %dx%d
number of chars : %d
general height : %d&&&%(img_w,img_h,nums,ch)
#打印所有字符数据(unicode代码、宽、高、坐标x、y)
for char in font_data:
&&& w,h,x,y=font_data[char]
&&& print &X&%char,x,y,w,h
转换数据为游戏所需格式
字库生成器为了通用性,所以设计上是输出部分关键数据,然后根据具体游戏再转换为对应格式。
以下以相对较为简单的Chrome4引擎为例。该引擎的字库使用纯文本定义,每个字符需要6个相关参数。具体如下:
Char( unicode值, 实际宽度, 左顶点x坐标, 左顶点y坐标, 右下顶点x坐标, 右下顶点y坐标)
根据上面的定义,有些数据在读取后可以直接使用,而有些则需要进行计算。因此得到以下代码:
from urfFontReader import ReadUrfFontInfo
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r'1')
#创建一个文件用于写入输出文件
fm = open('mid_28.fm','w')
#先写入游戏字库需要的基本信息
fm.write('''Name(&mid&)
MapWidth(%d)
MapHeight(%d)
FontHeight(%d)
'''%(img_w,img_h,ch))
#遍历所有数据,写入每个字符的定义
for char,(w,h,x,y) in font_data.iteritems():
&&& fm.write(&Char(%d, %d, %d, %d, %d, %d)n&%(char, w, x, y, x+w, y+ch))
由于字典类型是没有顺序的,所以输出的文件会有点乱。但稍加改动就可以按unicode代码的顺序输出数据。
&#先将所有项的列表保存到一个变量
data = font_data.items()
#对这个列表排序
data.sort()
#再通过排序后的列表输出
for char,(w,h,x,y) in data:
&&& fm.write(&Char(%d, %d, %d, %d, %d, %d)n&%(char, w, x, y, x+w, y+ch))
以上介绍了一个相对简单的,保存为游戏可用格式的例子。在以后的文章中我会提供更多更复杂的例子。
分割字库图片
有很多情况需要分割字库图片。比如对于一些老显卡,可能不支持以上的纹理大小,某些游戏只支持固定大小纹理等等。分割字库的思路很简单。先打开一个字库,然后将字符挨个复制到新大小的图片中,当装不下时就保存当前图片再新建另外一张图片。借助PIL库,很容易完成这个任务。
import Image
from urfFontReader import ReadUrfFontInfo
(img_w,img_h,nums,ch),font_data = ReadUrfFontInfo(r'1')
#设置分割成多大
max_w = 512 #目标宽度
max_h = 512 #目标高度
#打开我们的字库图片
img_in = Image.open('1.png')
img_idx = 0 #图片序号/计数器
cx = 0 #在目标图片中的x坐标
cy = 0 #在目标图片中的y坐标
#新建一张图像用于输出
img_out = Image.new(&RGBA&,(max_w,max_h))
#遍历所有数据进行分割
for char,(w,h,x,y) in font_data.iteritems():
&&& #如果下一个字符粘贴后超出目标宽度则切换到下一行
&&& if cx + w & max_w:
&&&&&&& cy += ch #换行
&&&&&&& #如果余下高度不足容纳一个字符则新建另一张图片
&&&&&&& if cy + ch & max_h:
&&&&&&&&&&& cy = 0 #y坐标归零
&&&&&&&&&&& img_out.save('s_d.png'%img_idx) #保存当前图片
&&&&&&&&&&& img_out = Image.new(&RGBA&,(max_w,max_h)) #新建另一张图片
&&&&&&&&&&& img_idx += 1 #图片序号+1
&&&&&&& cx = 0 #x坐标归零
&&& #从原图复制指定字符到新图片(这里特意分为两步以便看得更清楚,实际只需一步)
&&& box = img_in.crop((x,y,x+w,y+ch)) #复制原图的指定区域
&&& img_out.paste(box,(cx,cy)) #粘贴到新图的当前位置
&& &#这里可以插入保存字符信息的代码
&&& #位置向前移动一个字符
&&& cx += w
#结束后保存未保存的图片
img_out.save('s_d.png'%img_idx)
这里所用的crop 方法需要提供一个&box&参数,这个参数实际是一个列表,里面需要依序提供矩形的左上顶点和右下顶点的x、y坐标,然后该方法返回一个image对象,里面保存着截取的内容,相当于复制图片中的选定区域。然后再用paste 方法粘贴到指定位置。更多信息请参考PIL文档的imgae模块部分:/library/pil/handbook/image.htm
以上只是最基本的字库图片分割方法。有时实际要求要复杂得多,比如我要每个字符上下左右都留4像素的边要如何做呢?对此,我想我是没义务多做解释的是吧?
将图片转换为DDS格式
DDS是许多DX游戏常用的纹理格式。NVIDIA Texture Tools 可以将多数格式的图片转换为DDS格式。虽然python也有办法保存DDS格式,但目前的脚本压缩速度都实在太慢。
转换DDS主要用到的是nvcompress这个工具。用法如下:
$ nvcompress [options] infile [outfile]
详细参数表参考&NVIDIA_Texture_Tools_README.txt&。
这里介绍一下这个工具与脚本结合的方法。这是一个命令行工具,所以最简单的方法就是直接命令行调用。
以分割图片的代码为例:
import os #导入os库
#新建函数SaveDDS
def SaveDDS():
&&& img_out.save('tmp.png') #保存一个临时文件
&&& os.system(r'..nvttnvcompress.exe -nocuda -nomips -bc3 tmp.png s_d.dds'%img_idx) #通过命令行调用nvcompress,注意路径
&&& os.remove('tmp.png') #最后删除临时文件
#在需要保存图片的位置直接调用这个函数
这里保存的是一个普通的带透明层的dds图片。而不同游戏又有不同要求,可能需要你多加注意。
写在后面的话
之所以要使用脚本,其目的主要是为了快速实现我们的想法,方便地开发我们需要的工具。而执行效率并不是我们的主要目的,这点一定要记住。如果能兼顾效率的话当然最好,但如果为了追求效率而减慢了开发速度那就失去了使用脚本的意义了
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
[商业源码]&
Copyright &
All Rights Reserved后使用快捷导航没有帐号?
查看: 13469|回复: 657
【冰鹰找字】触动识别文字库 &识字&&找字&插件
马上注册,结交更多好友,享用更多功能,让你轻松玩转触动精灵。
才可以下载或查看,没有帐号?
本帖最后由 bingying 于
12:43 编辑
触动没有识别文字的,多点找色虽然能满足大部分需求 但是它比较方便的只是识别固定位置,或者有规律的位置变动的文字
根据个人需要,自己写了这么一个库,效率很低,也就只能当玩具.
识别等级.jpg (123.52 KB, 下载次数: 15)
13:45 上传
两个字的字库&&识别范围也就 等级那一小块耗时单位为毫秒
识别金币.jpg (80.26 KB, 下载次数: 5)
13:46 上传
这个是识别金币
效率不尽人意,上传源码希望有达者再加改进
字库跟大漠字库兼容,只是字库文件要保存问utf8格式
源码下载地址
游客,如果您要查看本帖隐藏内容请
根据lua版的识别原理,用c++写成了触动的插件
识别效率大大增加
快速识别.jpg (81.54 KB, 下载次数: 39)
19:21 上传
在此特别感谢:[苏大]的大力指导
同时技术细节已经提供给了[苏大]
相信很块触动就能内置此功能,
衷心祝愿触动越办越好
[PHP] 纯文本查看 复制代码local by = require &by&
init(&0&,1)
mSleep(2000)
by.SetDict(0,&/User/Media/TouchSprite/res/字库.txt&)
local t = os.clock()
local s = by.Ocr(0,
639,0xf8f3ef,0x080c10,0.85)
dialog(string.format(&识别:%s
耗时:%d&,s,(os.clock()-t)*1000),0)
目前此库里只有 Ocr 和 SetDict&&UseDict
x,y,x1,y1,颜色,色偏,相似度
Ocr(0,&&0,1134,&&639,0xf8f3ef,0x080c10,0.85)
返回 识别到的字符串
当然别全屏识别,全屏识别的效率还是很差的,局部识别的话效率还可以接受
id,字库路径& &
SetDict(0,&/User/Media/TouchSprite/res/字库.txt&)
成功返回 1
失败返回 0
一般都会成功
UseDict(0)
此函数用于切换字库的
这个版本支持100个字库&&id取值范围是0-99
点阵的获取只要用过大漠的应该都会
就用大漠工具提取就可以
1.修复识别有死角的问题
1. 添加FindStr函数,调用格式 by.FindStr(923,&&155,965,&&455,&朱雀&,0xd8cd25,0x2)
注意:如果范围较大的话 查找起来会很慢,尽量把单个字库文件里的字放少一点 , 需要用的时候用UseDict 切换&&UseDict的效率很高的 不会带来性能损失
此函数只支持找单个字符 如果想找多个字符 请把多个字符采集为1个点阵数据比如:
F4FFFFF8CC218CCC3BA09FF207CC04C08C10C20C4$朱雀$0.0.302$20
参数:& &x,y,x1,y1,字符串,颜色,色偏,相似度
下载地址已更新
游客,如果您要查看本帖隐藏内容请
支持分享,大吉大利!
学习了,目前只是用自己建的字库来识别,效率 比较有限
好东西 学习下
学习支持,楼主好人好报
好人一生平安
这么好的贴子为什么不申精
帖子推荐 /5
苏大出品,让你的开发效率增加百倍!
官方编辑器,支持远程调试和运行。
不会用showUI,看看桃子的世界吧~
触动精灵开发者平台内测几个月以来,收到了很多开发者的建议和反馈,你们的积极参与让开发者平台越来越好用。
使用触动精灵最新版扫一扫即可下载,完全免费的脚本哟~
Powered by

参考资料

 

随机推荐