菜鸟教程小白 发表于 2022-12-13 08:31:47

ios - iOS 上的 PNG 验证


                                            <p><p>在 iOS 上编写 map 应用程序,使用 OpenStreetMap 瓦片。
map 瓦片图像被异步下载并存储在字典中,或保存在 SQLite DB 中。</p>

<p>有时,无论出于何种原因,在尝试渲染 map 图 block 图像时,我会收到以下错误:<br/>
<code>ImageIO: <ERROR> PNGinvalid distance too far back</code></p>

<p>这会导致我的 map 上出现令人讨厌的黑色方 block 。</p>

<p>这是发生这种情况的一段代码:</p>

<pre><code>NSData *imageData = ;
if (imageData != nil) {
    NSLog(@&#34;Obtained image data\n&#34;);
    UIImage *img = [ retain];
    // Perform the image render on the current UI context.
    // ERROR OCCURS BETWEEN PUSH AND POP
    UIGraphicsPushContext(context);
    blendMode:kCGBlendModeNormal alpha:1.0f];
    UIGraphicsPopContext();
    ;
}
</code></pre>

<p>现在,我正在寻找一种在尝试将 png 渲染到我的 map 之前确保它有效的方法。</p>

<p><b>编辑:</b>系统偶尔也会抛出这个错误:<br/>
<code>ImageIO: <ERROR> PNGIDAT: CRC 错误</code></p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我在其他问题中发现了这一点,并整理了为我解决问题的方法。希望对您有所帮助。</p>

<p>PNG 格式有几个内置检查。每个“ block ”都有一个 CRC32 检查,但要检查您是否需要阅读完整的文件。</p>

<p>更基本的检查(当然不是万无一失的)是读取文件的开头和结尾。</p>

<p>前 8 个字节应始终为以下(十进制)值 { 137, 80, 78, 71, 13, 10, 26, 10 } (ref)。特别是,第二到第四个字节对应于 ASCII 字符串“PNG”。</p>

<p>十六进制:</p>

<pre><code>89 50 4e 47 0d 0a 1a 0a
.. PNG...........
</code></pre>

<p>您还可以检查文件的最后 12 个字节(IENDblock )。中间 4 个字节应对应 ASCII 字符串“IEND”。更具体地说,最后 12 个字节应该是(以十六进制表示):</p>

<pre><code>00 00 00 00 49 45 4e 44 ae 42 60 82
........... IEND...........
</code></pre>

<p>(严格来说,PNG 文件以这 12 个字节结尾并不是必须的,IENDblock 本身表示 PNG 流的结束,因此文件原则上可以有额外的尾随字节,这些字节会被PNG 阅读器。实际上,这是极不可能的)。</p>

<p>这是一个实现:</p>

<pre><code>- (BOOL)dataIsValidPNG:(NSData *)data
{
    if (!data || data.length &lt; 12)
    {
      return NO;
    }

    NSInteger totalBytes = data.length;
    const char *bytes = (const char *);

    return (bytes == (char)0x89 &amp;&amp; // PNG
            bytes == (char)0x50 &amp;&amp;
            bytes == (char)0x4e &amp;&amp;
            bytes == (char)0x47 &amp;&amp;
            bytes == (char)0x0d &amp;&amp;
            bytes == (char)0x0a &amp;&amp;
            bytes == (char)0x1a &amp;&amp;
            bytes == (char)0x0a &amp;&amp;

            bytes == (char)0x00 &amp;&amp; // IEND
            bytes == (char)0x00 &amp;&amp;
            bytes == (char)0x00 &amp;&amp;
            bytes == (char)0x00 &amp;&amp;
            bytes == (char)0x49 &amp;&amp;
            bytes == (char)0x45 &amp;&amp;
            bytes == (char)0x4e &amp;&amp;
            bytes == (char)0x44 &amp;&amp;
            bytes == (char)0xae &amp;&amp;
            bytes == (char)0x42 &amp;&amp;
            bytes == (char)0x60 &amp;&amp;
            bytes == (char)0x82);
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - iOS 上的 PNG 验证,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/6824357/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/6824357/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - iOS 上的 PNG 验证