在PHP fopen()神秘丢弃的字节

时间:2015-12-31 23:24:58

标签: php ajax

我在图像文件中使用fopen()和二进制读取参数(“rb”),如下所示:

while (fgetc($imageExposed) !== false) {
        $binaryString = fgetc($imageExposed);
        echo bin2hex($binaryString);
}

在读取图像时,位于文件指针的字符在将它们转换为十六进制后会被回显:

function imageAnalysis(dynamicObject, gameObjectDesc) {
    phpCourier = new XMLHttpRequest();

    phpCourier.onreadystatechange = function () {
        if (phpCourier.readyState === 4 && phpCourier.status === 200) {
            var imageParserTest = document.createElement('canvas'),

                stringBox = [],
                base = 16,
                hexNumbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],
                output,
                stringBoxCleaner,
                dimX = 24,
                dimY = 47,
                channels = "rgba",
                colourMap = [],
                colourStep = 0,
                chunkString,
                bitMapping;

            imageParserTest.style.zIndex = 90000;

            for (bitCounter = 0; bitCounter < phpCourier.response.length; bitCounter += 1) {

                stringBox.push(phpCourier.response.substr(bitCounter, 1));
                stringBox.push(phpCourier.response.substr(bitCounter + 1, 1));                

                colourMap.push(channels.substr(colourStep, 1));

                if (colourStep !== channels.length) {
                    colourStep += 1;
                }

                if (colourStep === channels.length) {
                    colourStep = 0;
                }

                /*if (stringBox[0] + stringBox[1] > 128) {
                    if (colourMap[bitCounter] === "a") {
                        output = 255;
                    } else if (colourMap[bitCounter] === "b") {
                        output = 255;
                    } else if (colourMap[bitCounter] === "g") {
                        output = 255;
                    } else if (colourMap[bitCounter] === "r") {
                        output = 255;
                    }
                } else {
                    if (colourMap[bitCounter] === "a") {
                        output = 255;
                    } else if (colourMap[bitCounter] === "b") {
                        output = 0;
                    } else if (colourMap[bitCounter] === "g") {
                        output = 0;
                    } else if (colourMap[bitCounter] === "r") {
                        output = 0;
                    }
                }*/

                output = stringBox[0] + stringBox[1];

                //console.log(phpCourier.response.substr(bitCounter, 8));
                //console.log(phpCourier.response);

                //Uint8ClampedArray[bitCounter] = output;

                if (phpCourier.response.substr(bitCounter, 4) === "4454") {//"49444154") {
                    Uint8ClampedArray = new Uint8ClampedArray(phpCourier.response.length - bitCounter - 9);
                    bitMapping = true;
                    console.log("bah");
                }

                if (bitMapping === true) {
                    Uint8ClampedArray[(phpCourier.response.length - bitCounter - 9)] = output;
                    console.log(phpCourier.response.substr(bitCounter, 2));
                }

                stringBox = [];
            }

            console.log(Uint8ClampedArray);

            console.log("Base Data Length " + phpCourier.response.length);
            console.log("Required Dimensions " + dimX * dimY * 4);
            console.log("Output Length " + Uint8ClampedArray.length);

            //pipedImage = new ImageData(Uint8ClampedArray, dimX, dimY);

            //document.body.appendChild(imageParserTest);

            //imageParserTest.getContext("2d").putImageData(pipedImage, dimX, dimY);

            //console.log(pipedImage);

            //console.log(imageParserTest.getContext("2d").getImageData(39, 66, 39, 66));

            console.log(phpCourier.response.length);
            console.log(phpCourier.response);
        }
    };

    phpCourier.open("POST", "bitManip.php", true);
    phpCourier.send("gameObject=" + dynamicObject + "&description=" + gameObjectDesc);
}

imageAnalysis(aeolus, "Basic");

不知何故,该过程每隔一个字节丢失一次 - 例如,第一个八位字节是50 47 0A 0A(PG &lt; LF&gt;,用ASCII)而不是89 50 4E 47(.PNG)。什么可以使这种情况发生?

在一个可能相关的说明中,图像在处理后膨胀,从~4415B到4526 - 尽管如上所述丢弃了数据。虽然在我的位编辑器(Frhed)中包含图像位图(IDAT和IEND之间)的段是980B,但是在处理之后它会莫名其妙地扩展到1554B(IDAT近似为DT [44 54])而不会影响回显的数据总量

背景:图像为4.4KB PNG;它正如上面在PHP中所描述的那样进行处理,然后通过以下AJAX调用接收回送的数据,然后将其推送到控制台; 4454之后的数据(表示IDAT块)被推送到Uint8ClampedArray以显示 - 或者如果没有丢弃字节的话。数据仍然被发送到数组,但它没有被转换为进程的十进制数或通过ImageData推送到canvas元素。

AFAIK Uint8ClampedArray需要十进制数据才能工作,所以我也写了一个十六进制/十进制转换器。因为问题出现在原始的AJAX响应中,所以没有必要显示十进制数据或它的ImageData表示,所以这就是为什么我已经包含了这些数据但阻止它们产生输出。

SELECT DISTINCT p.*, slc( ?, ?, p.latitude, p.longitude)*1000 as distance from xxx as up, xxx as p 
WHERE (up.user_id IN (
    select followee_id from user_followers WHERE owner_id = ?) OR up.user_id = ?) 
    AND up.place_id = p.id order by distance desc

1 个答案:

答案 0 :(得分:4)

您为每个循环调用fgetc()两次

首先在行

while (fgetc($imageExposed) !== false) {

并且不以任何方式使用该字节

然后在

$binaryString = fgetc($imageExposed);
你正在展示的

当然,它忽略了所有其他字节

将其更改为

while (($binaryString = fgetc($imageExposed)) !== false) {
    echo bin2hex($binaryString);
}

while (!feof($imageExposed)) {
    $binaryString = fgetc($imageExposed);
    echo bin2hex($binaryString);
}