如何从 plist 文件中提取 png 图像?

发布于 2024-11-08 18:40:35 字数 111 浏览 0 评论 0原文

我目前有一组 plist 文件。里面是png图片,有些文件有很多图片。我用的是win64 vista。

我已经寻找了专门为此目的的东西,例如 FileJuicer,但这仅适用于 mac 用户。

I currently have a set of plist files. Inside are png images, some files have numerous images. I'm using win64 vista.

I've looked for things specifically for this such as FileJuicer, but that is only for mac users.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

牵你手 2024-11-15 18:40:35

我编写了此脚本来解压 TexturePacker

首先,确保 png 和 plist 文件都在同一目录中,在我的例子中: freeGifts.plist 和 freeGifts.png

其次,与 unpack_plist.py 相同的以下脚本

然后, python unpack_plist .py freeGifts,它会生成很多png文件到名为freeGifts的目录

要求:python,PIL

#! /usr/lical/bin/python
import os,Image,sys
from xml.etree import ElementTree

def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1])
    return d

def gen_png_from_plist(plist_filename, png_filename):
    file_path = plist_filename.replace('.plist', '')
    big_image = Image.open(png_filename)
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    for k,v in plist_dict['frames'].items():
        rectlist = to_list(v['frame'])
        width = int( rectlist[3] if v['rotated'] else rectlist[2] )
        height = int( rectlist[2] if v['rotated'] else rectlist[3] )
        box=( 
            int(rectlist[0]),
            int(rectlist[1]),
            int(rectlist[0]) + width,
            int(rectlist[1]) + height,
            )
        sizelist = [ int(x) for x in to_list(v['sourceSize'])]
        rect_on_big = big_image.crop(box)
        result_image = Image.new('RGBA', sizelist, (0,0,0,0))
        result_box=(
            ( sizelist[0] - width )/2,
            ( sizelist[1] - height )/2,
            ( sizelist[0] + width )/2,
            ( sizelist[1] + height )/2
            )
        result_image.paste(rect_on_big, result_box, mask=0)
        if v['rotated']:
            result_image = result_image.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')
        print outfile, "generated"
        result_image.save(outfile)

if __name__ == '__main__':
    filename = sys.argv[1]
    plist_filename = filename + '.plist'
    png_filename = filename + '.png'
    if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
        gen_png_from_plist( plist_filename, png_filename )
    else:
        print "make sure you have boith plist and png files in the same directory"

I have written this script to unpack png files in the plist file packed by TexturePacker

First, make sure you have both the png and plist files in the same directory, in my case: freeGifts.plist and freeGifts.png

Second, same the following script as unpack_plist.py

Then, python unpack_plist.py freeGifts, it will generate lots of png files to a directory named freeGifts

Requirement: python, PIL

#! /usr/lical/bin/python
import os,Image,sys
from xml.etree import ElementTree

def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1])
    return d

def gen_png_from_plist(plist_filename, png_filename):
    file_path = plist_filename.replace('.plist', '')
    big_image = Image.open(png_filename)
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    for k,v in plist_dict['frames'].items():
        rectlist = to_list(v['frame'])
        width = int( rectlist[3] if v['rotated'] else rectlist[2] )
        height = int( rectlist[2] if v['rotated'] else rectlist[3] )
        box=( 
            int(rectlist[0]),
            int(rectlist[1]),
            int(rectlist[0]) + width,
            int(rectlist[1]) + height,
            )
        sizelist = [ int(x) for x in to_list(v['sourceSize'])]
        rect_on_big = big_image.crop(box)
        result_image = Image.new('RGBA', sizelist, (0,0,0,0))
        result_box=(
            ( sizelist[0] - width )/2,
            ( sizelist[1] - height )/2,
            ( sizelist[0] + width )/2,
            ( sizelist[1] + height )/2
            )
        result_image.paste(rect_on_big, result_box, mask=0)
        if v['rotated']:
            result_image = result_image.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')
        print outfile, "generated"
        result_image.save(outfile)

if __name__ == '__main__':
    filename = sys.argv[1]
    plist_filename = filename + '.plist'
    png_filename = filename + '.png'
    if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
        gen_png_from_plist( plist_filename, png_filename )
    else:
        print "make sure you have boith plist and png files in the same directory"
晒暮凉 2024-11-15 18:40:35

哈哈,这都是史蒂夫·乔布斯所做的。您可以使用 ChadBurggraf 的库在 C# 中解析 plist https://github.com/ChadBurggraf/plists-cs。但正如评论中所讨论的,您想要的文件可能不在 plist 文件中。

Lol, this is all Steve Jobs' doing. You could parse the plist in C# using ChadBurggraf's library https://github.com/ChadBurggraf/plists-cs. But as discussed in the comments, the files you want probably aren't in the plist file.

人疚 2024-11-15 18:40:35

感谢肖恩·Z。首先。
但我发现rotate不好,而且ygweric的patch也不够好。
因为当 png 包含 jpg 文件(模式 P)时,它会失败。有时透明会变成黑色背景。
我尝试修复此问题和我的代码如下:

    #! /usr/lical/bin/python
    import os,Image,sys
    from xml.etree import ElementTree

    def tree_to_dict(tree):
        d = {}
        for index, item in enumerate(tree):
            if item.tag == 'key':
                if tree[index+1].tag == 'string':
                    d[item.text] = tree[index + 1].text
                elif tree[index + 1].tag == 'true':
                    d[item.text] = True
                elif tree[index + 1].tag == 'false':
                    d[item.text] = False
                elif tree[index+1].tag == 'dict':
                    d[item.text] = tree_to_dict(tree[index+1])
        return d

    def gen_png_from_plist(plist_filename, png_filename):
        file_path = plist_filename.replace('.plist', '')
        big_image = Image.open(png_filename)
        root = ElementTree.fromstring(open(plist_filename, 'r').read())
        plist_dict = tree_to_dict(root[0])
        to_list = lambda x: x.replace('{','').replace('}','').split(',')
        for k,v in plist_dict['frames'].items():
            rectlist = to_list(v['frame'])
            width = int( rectlist[3] if v['rotated'] else rectlist[2] )
            height = int( rectlist[2] if v['rotated'] else rectlist[3] )
            box=( 
                int(rectlist[0]),
                int(rectlist[1]),
                int(rectlist[0]) + width,
                int(rectlist[1]) + height,
                )
            sizelist = [ int(x) for x in to_list(v['sourceSize'])]
            rect_on_big = big_image.crop(box)

            if v['rotated']:
                rect_on_big = rect_on_big.rotate(90)

            result_image = Image.new('RGBA', sizelist, (0,0,0,0))
            if v['rotated']:
                result_box=(
                    ( sizelist[0] - height )/2,
                    ( sizelist[1] - width )/2,
                    ( sizelist[0] + height )/2,
                    ( sizelist[1] + width )/2
                    )
            else:
                result_box=(
                    ( sizelist[0] - width )/2,
                    ( sizelist[1] - height )/2,
                    ( sizelist[0] + width )/2,
                    ( sizelist[1] + height )/2
                    )
            result_image.paste(rect_on_big, result_box, mask=0)

            if not os.path.isdir(file_path):
                os.mkdir(file_path)
            outfile = (file_path+'/' + k).replace('gift_', '')
            print outfile, "generated"
            result_image.save(outfile)

    if __name__ == '__main__':
        filename = sys.argv[1]
        plist_filename = filename + '.plist'
        png_filename = filename + '.png'
        if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
            gen_png_from_plist( plist_filename, png_filename )
        else:
            print "make sure you have boith plist and png files in the same directory"

Thanks to Sean.Z. first.
But I found that the rotate is not good, and ygweric's patch is not good enough.
because it will fail when the png include jpg file(mode P). and sometime Transparent will became black background.
I try to fix this and my code as below:

    #! /usr/lical/bin/python
    import os,Image,sys
    from xml.etree import ElementTree

    def tree_to_dict(tree):
        d = {}
        for index, item in enumerate(tree):
            if item.tag == 'key':
                if tree[index+1].tag == 'string':
                    d[item.text] = tree[index + 1].text
                elif tree[index + 1].tag == 'true':
                    d[item.text] = True
                elif tree[index + 1].tag == 'false':
                    d[item.text] = False
                elif tree[index+1].tag == 'dict':
                    d[item.text] = tree_to_dict(tree[index+1])
        return d

    def gen_png_from_plist(plist_filename, png_filename):
        file_path = plist_filename.replace('.plist', '')
        big_image = Image.open(png_filename)
        root = ElementTree.fromstring(open(plist_filename, 'r').read())
        plist_dict = tree_to_dict(root[0])
        to_list = lambda x: x.replace('{','').replace('}','').split(',')
        for k,v in plist_dict['frames'].items():
            rectlist = to_list(v['frame'])
            width = int( rectlist[3] if v['rotated'] else rectlist[2] )
            height = int( rectlist[2] if v['rotated'] else rectlist[3] )
            box=( 
                int(rectlist[0]),
                int(rectlist[1]),
                int(rectlist[0]) + width,
                int(rectlist[1]) + height,
                )
            sizelist = [ int(x) for x in to_list(v['sourceSize'])]
            rect_on_big = big_image.crop(box)

            if v['rotated']:
                rect_on_big = rect_on_big.rotate(90)

            result_image = Image.new('RGBA', sizelist, (0,0,0,0))
            if v['rotated']:
                result_box=(
                    ( sizelist[0] - height )/2,
                    ( sizelist[1] - width )/2,
                    ( sizelist[0] + height )/2,
                    ( sizelist[1] + width )/2
                    )
            else:
                result_box=(
                    ( sizelist[0] - width )/2,
                    ( sizelist[1] - height )/2,
                    ( sizelist[0] + width )/2,
                    ( sizelist[1] + height )/2
                    )
            result_image.paste(rect_on_big, result_box, mask=0)

            if not os.path.isdir(file_path):
                os.mkdir(file_path)
            outfile = (file_path+'/' + k).replace('gift_', '')
            print outfile, "generated"
            result_image.save(outfile)

    if __name__ == '__main__':
        filename = sys.argv[1]
        plist_filename = filename + '.plist'
        png_filename = filename + '.png'
        if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
            gen_png_from_plist( plist_filename, png_filename )
        else:
            print "make sure you have boith plist and png files in the same directory"
漆黑的白昼 2024-11-15 18:40:35

感谢 Sean.Z。
对于 unpack_plist.py,您需要:
1: PIL已安装在您的电脑上。
2:使用python 2.5
python2.5 unpack_plist.py Birdfly

否则你会失败。
-----2013-07-25--
对于一些旋转的plist,上面的脚本可能有一些错误。我将其修改如下:



#python2.5 unpack_plist.py birdfly 


#! /usr/lical/bin/python
import os,Image,sys
from xml.etree import ElementTree

    def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1])
    return d

    def gen_png_from_plist(plist_filename, png_filename):
    file_path = plist_filename.replace('.plist', '')
    big_image = Image.open(png_filename)
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    for k,v in plist_dict['frames'].items():
        print "-----start\n----------"
        rectlist = to_list(v['frame'])
        print rectlist, "--------rectlist"
        width = int( rectlist[3] if v['rotated'] else rectlist[2] )
        height = int( rectlist[2] if v['rotated'] else rectlist[3] )
        print width,height,"----width,height"
        box=( 
            int(rectlist[0]),
            int(rectlist[1]),
            int(rectlist[0]) + width,
            int(rectlist[1]) + height,
            )
        # bos is start & end point
        print box,"-----_box-"
        print v['rotated'], "---rotated"

        sizelist = [ int(x) for x in to_list(v['sourceSize'])]
        rect_on_big = big_image.crop(box)
        '''
        result_image = Image.new('RGBA', sizelist, (0,0,0,0))
        result_box=(
            ( sizelist[0] - width )/2,
            ( sizelist[1] - height )/2,
            ( sizelist[0] + width )/2,
            ( sizelist[1] + height )/2
            )
        result_image.paste(rect_on_big, result_box, mask=0)
        if v['rotated']:
            result_image = result_image.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')
        print result_box,"-----result_box-"
        print outfile, "generated"
        # result_image.save(outfile)
        '''

        if v['rotated']:
            rect_on_big = rect_on_big.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')

        rect_on_big.save(outfile);

    if __name__ == '__main__':
    filename = sys.argv[1]
    plist_filename = filename + '.plist'
    png_filename = filename + '.png'
    if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
        gen_png_from_plist( plist_filename, png_filename )
    else:
        print "make sure you have boith plist and png files in the same directory"

Thanks to Sean.Z.
for the unpack_plist.py, you need:
1: PIL have been installed on you pc.
2: use python 2.5
python2.5 unpack_plist.py birdfly

or you will fail.
-----2013-07-25--
for some plist which is rotated, the above spcript may have some bugs. i modify it like following:



#python2.5 unpack_plist.py birdfly 


#! /usr/lical/bin/python
import os,Image,sys
from xml.etree import ElementTree

    def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1])
    return d

    def gen_png_from_plist(plist_filename, png_filename):
    file_path = plist_filename.replace('.plist', '')
    big_image = Image.open(png_filename)
    root = ElementTree.fromstring(open(plist_filename, 'r').read())
    plist_dict = tree_to_dict(root[0])
    to_list = lambda x: x.replace('{','').replace('}','').split(',')
    for k,v in plist_dict['frames'].items():
        print "-----start\n----------"
        rectlist = to_list(v['frame'])
        print rectlist, "--------rectlist"
        width = int( rectlist[3] if v['rotated'] else rectlist[2] )
        height = int( rectlist[2] if v['rotated'] else rectlist[3] )
        print width,height,"----width,height"
        box=( 
            int(rectlist[0]),
            int(rectlist[1]),
            int(rectlist[0]) + width,
            int(rectlist[1]) + height,
            )
        # bos is start & end point
        print box,"-----_box-"
        print v['rotated'], "---rotated"

        sizelist = [ int(x) for x in to_list(v['sourceSize'])]
        rect_on_big = big_image.crop(box)
        '''
        result_image = Image.new('RGBA', sizelist, (0,0,0,0))
        result_box=(
            ( sizelist[0] - width )/2,
            ( sizelist[1] - height )/2,
            ( sizelist[0] + width )/2,
            ( sizelist[1] + height )/2
            )
        result_image.paste(rect_on_big, result_box, mask=0)
        if v['rotated']:
            result_image = result_image.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')
        print result_box,"-----result_box-"
        print outfile, "generated"
        # result_image.save(outfile)
        '''

        if v['rotated']:
            rect_on_big = rect_on_big.rotate(90)
        if not os.path.isdir(file_path):
            os.mkdir(file_path)
        outfile = (file_path+'/' + k).replace('gift_', '')

        rect_on_big.save(outfile);

    if __name__ == '__main__':
    filename = sys.argv[1]
    plist_filename = filename + '.plist'
    png_filename = filename + '.png'
    if (os.path.exists(plist_filename) and os.path.exists(png_filename)):
        gen_png_from_plist( plist_filename, png_filename )
    else:
        print "make sure you have boith plist and png files in the same directory"
一杯敬自由 2024-11-15 18:40:35

如果您的 PC 中有 JRE 或者您可能已经安装了 JRE,那么您可以使用我创建的工具来解压 .plist 文件。它还支持 LibGdx 项目中使用的 .pack 文件和 Unity 等许多引擎中使用的 .xml 文件来打包纹理。

https://github.com/itsabhiaryan/TextureUnPacker

If you have JRE in your PC or you may be install then you can use a tool which i create to unpack .plist file. It also has support .pack file that use in LibGdx projects and .xml file used in many engine like unity to pack texture.

https://github.com/itsabhiaryan/TextureUnPacker

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文