• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - iOS 上的 PNG 验证

[复制链接]
菜鸟教程小白 发表于 2022-12-13 08:31:47 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

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

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

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

这是发生这种情况的一段代码:

NSData *imageData = [TileDownloader RetrieveDataAtTileXint)tilex Yint)tiley Zoomint)zoomLevel];  
if (imageData != nil) {
    NSLog(@"Obtained image data\n");
    UIImage *img = [[UIImage imageWithData:imageData] retain];
    // Perform the image render on the current UI context.  
    // ERROR OCCURS BETWEEN PUSH AND POP
    UIGraphicsPushContext(context);
    [img drawInRect:[self rectForMapRect:mapRect] blendMode:kCGBlendModeNormal alpha:1.0f];
    UIGraphicsPopContext();
    [img release];
}

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

编辑:系统偶尔也会抛出这个错误:
ImageIO: PNGIDAT: CRC 错误



Best Answer-推荐答案


我在其他问题中发现了这一点,并整理了为我解决问题的方法。希望对您有所帮助。

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

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

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

十六进制:

89 50 4e 47 0d 0a 1a 0a
.. P  N  G  ...........

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

00 00 00 00 49 45 4e 44 ae 42 60 82
........... I  E  N  D  ...........

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

这是一个实现:

- (BOOL)dataIsValidPNGNSData *)data
{
    if (!data || data.length < 12)
    {
        return NO;
    }

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

    return (bytes[0] == (char)0x89 && // PNG
            bytes[1] == (char)0x50 &&
            bytes[2] == (char)0x4e &&
            bytes[3] == (char)0x47 &&
            bytes[4] == (char)0x0d &&
            bytes[5] == (char)0x0a &&
            bytes[6] == (char)0x1a &&
            bytes[7] == (char)0x0a &&

            bytes[totalBytes - 12] == (char)0x00 && // IEND
            bytes[totalBytes - 11] == (char)0x00 &&
            bytes[totalBytes - 10] == (char)0x00 &&
            bytes[totalBytes - 9] == (char)0x00 &&
            bytes[totalBytes - 8] == (char)0x49 &&
            bytes[totalBytes - 7] == (char)0x45 &&
            bytes[totalBytes - 6] == (char)0x4e &&
            bytes[totalBytes - 5] == (char)0x44 &&
            bytes[totalBytes - 4] == (char)0xae &&
            bytes[totalBytes - 3] == (char)0x42 &&
            bytes[totalBytes - 2] == (char)0x60 &&
            bytes[totalBytes - 1] == (char)0x82);
}

关于ios - iOS 上的 PNG 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6824357/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap