用PHP解压平铺TMX文件内容

用PHP解压平铺TMX文件内容,php,xml,gzip,base64,Php,Xml,Gzip,Base64,从.tmx(平铺)文件中提取图层内容时遇到问题。 我想在PHP中获得完整的未压缩数据,并对其制作一个小图像。 获取标题信息,如宽度、高度等并没有问题——SimpleXML正在那里完成它的工作。但不知何故,瓷砖层的解压缩不起作用 数据本身存储为base64和gzip编码字符串(类似于h4siaaaaaaac+3bORKAIBQEUVzuf2YTTSwEA/gL00EnJvJQsAjcSyk7EU3v+Jn3OI),但我甚至在获取base64解码代码时遇到问题(它只给我wierd字符,当我以平铺方式

从.tmx(平铺)文件中提取图层内容时遇到问题。 我想在PHP中获得完整的未压缩数据,并对其制作一个小图像。 获取标题信息,如宽度、高度等并没有问题——SimpleXML正在那里完成它的工作。但不知何故,瓷砖层的解压缩不起作用

数据本身存储为base64和gzip编码字符串(类似于
h4siaaaaaaac+3bORKAIBQEUVzuf2YTTSwEA/gL00EnJvJQsAjcSyk7EU3v+Jn3OI
),但我甚至在获取base64解码代码时遇到问题(它只给我wierd字符,当我以平铺方式重新打开地图并将其保存为“base64未压缩”结果只是一个空字符串(当然没有使用gzip解压缩)

我已经在网上搜索过了,看到了数据是如何被精确压缩的()。似乎我必须使用
gzinflate()
命令,而不是所有其他命令(例如gzuncompress),但这对我也不起作用

我现在掌握的代码如下:

<?php
  // Get the raw xml data
  $map_xml = new SimpleXML(file_get_contents("map.tmx"));
  $data = $map_xml["layer"][0]["data"]["@content"]; // I would make a loop here
  $content =gzinflate(base64_decode($map_content)); // gives me and error

  var_dump($data); // results in nothing
?>
Array
(
    [floor] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
            [3] => 1
            [4] => 1
            [5] => 1
            [6] => 1
            [7] => 1
            [8] => 1
        )

    [layer2] => Array
        (
            [0] => 0
            [1] => 0
            [2] => 1
            [3] => 0
            [4] => 1
            [5] => 0
            [6] => 1
            [7] => 1
            [8] => 0
        )

)

经过进一步的研究,我发现我应该使用zlib过滤器()。 现在我真的很困惑,我不知道我应该选什么-我再次问谷歌,得到了以下信息:。根据答案,在使用base64和gzip方法之前,我必须裁剪头部

现在我的问题是:我是否必须在之前裁剪出标题?如果是,我该怎么做? 如果没有,那么如何获取未压缩的数据


我真的希望有人能在这里帮助我

哇,这些PHP函数的名字太可怕了。首先是一些背景知识

您可能会遇到或能够产生三种格式。它们是:

  • 原始deflate,是压缩为deflate格式的数据,没有标题或尾部,在中定义
  • zlib是包装在紧凑型zlib标头和尾部中的原始放气数据,该标头和尾部由两字节标头和四字节Adler-32检查值组成,作为尾部,定义见
  • gzip,它是包装在gzip头和尾文件中的原始泄气数据,其中头文件至少有10个字节,可以更长,包含文件名、注释和/或额外字段,以及一个8字节尾文件,带有4字节CRC-32和未压缩长度模块2^32。此包装器在中定义。这是您将在后缀为
    .gz
    的文件中找到的数据
PHP函数
gzdeflate()
gzflate()
创建并解码原始deflate格式。PHP函数
gzcompress()
gzuncompress()
创建并解码zlib格式。这些函数的名称中都不应该有“gz”,因为它们都不能处理gzip格式!这将永远让试图创建或解码gzip格式数据的PHP程序员感到困惑

似乎有(但文档不清楚它们是否总是存在)PHP函数
gzencode()
gzdecode()
,如果我正确阅读了简洁的文档,默认情况下,这些函数创建并解码gzip格式
gzencode()
还有一个生成zlib格式的选项,我怀疑
gzdecode()
会尝试自动检测gzip或zlib格式并相应地进行解码。(这是所有这些功能使用的实际功能的一部分。)


zlib_encode()
zlib_decode()
的文档不完整(这些页面承认:“这个函数目前没有文档;只有它的参数列表可用”),因此很难判断它们是做什么的。对于
zlib_encode()
,有一个未记录的
encoding
字符串参数,如果您知道在字符串中放入什么,它可能允许您选择三种格式之一。
zlib_decode()
没有
encoding
参数,因此它可能尝试在三种格式中自动检测。

Php的gzflate和gzuncompress,如前所述,名称不正确。但是,我们可以利用gzinflate,它接受原始压缩数据。gzip头的长度为10字节,可以使用substr剥离。使用上面的示例,我尝试了以下方法:

$base64content = "H4sIAAAAAAAAC+3bORKAIBQEUVzuf2YTTSwEA/gL00EnJvJQsAjcSyk7EU3v+Jn3OI";
$compressed = substr( base64_decode($base64content), 10);
$content = gzinflate($compressed);
这将为您提供一个表示原始数据的字符串。您的TMX层主要由gid 0、2和3组成,因此只有在打印出来时才能看到空白。要获得有用的数据,您需要调用以下字符的ord:

$chars = str_split($content);
$values = array();
foreach($chars as $char) {
    $values[] = ord($char);
}
var_dump( implode(',', $values) );  // This gives you the equivalent of saving your TMX file with tile data stored as csv

希望这能有所帮助。

我知道这已经很旧了,但我已经花了一整天的时间在玩这段代码
对我的工作真的很挑剔。但是,这里有一个快速的函数,可以将TMX文件转换为每个层上每个磁贴的ID数组

其他的回答者帮我找出了我的错误所在

<?php

function getLayer($getLayerName = '')
{
    $xml = simplexml_load_file('level.tmx');
    $values = array();
    foreach($xml->layer as $child)
    {
        $name = $child->attributes()->name;

        if(!empty($getLayerName))
            if($name != $getLayerName)
                continue;

        $data = gzinflate(substr(base64_decode(trim($child->data)), 10));
        $chars = str_split($data);
        $i = 0;
        foreach($chars as $char)
        {
            $charID = ord($char);
            if($i % 4 == 0) // I'm only interested in the tile IDs
            {
                $values[(String) $name][] = $charID;
            }
            $i++;
        }
    }
    return $values;
}

print_r(getLayer());
//or you could use getLayer('LayerName') to get a single layer!

?>

希望这个函数对任何需要它的人都很方便。

你能添加完整的
.tmx
文件吗。。。要获得您正在处理的文件的完整详细信息,应自动启动;)遗憾的是,我只安装了PHP5.3.1——该版本中不存在zlib_encode()或zlib_decode()。也没有找到任何其他的实现它,我可以尝试。但是你的回答确实帮助我理解了不同方法之间的所有差异,非常感谢!是的,只有zlib_*函数不存在-这是我的问题,甚至base64decode也不起作用:(非常感谢!刚刚试用过,效果很好。这确实非常方便。非常感谢!@SpaceEmotion-不客气!我还在这里为它上了一堂课: