ipa 包中的 PNG 文件的正常化

本文介绍了在iOS开发中遇到的IPA包内PNG图片无法在非Apple系统正常显示的问题,以及如何通过修改Xcode项目设置,创建一个可执行程序和shell脚本来解决这个问题,最终实现PNG图片的正常化和压缩处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

  • 图片拖入 iOS 工程后, Xcode 会对其进行特殊处理, 导致图片能在 Apple 相关系统上正常显示, 其他系统都不能正常显示.
  • 之所以能在 Apple 相关系统上正常显示是因为苹果的底层方法实现就做了相应处理.

问题解决

  • 通过苹果的方法把这些特殊图片读入系统, 然后重新保存为 PNG 图片即可.

将这段代码加入你的 Mac 控制台工程, 生成一个可执行程序(如 ipaPNGnormalizer), 在命令行中使用即可, 第一个参数为需要正常化处理的 PNG 文件夹路径. 处理后会在这个目录下创建一个 decode 文件夹, 这个文件夹下存放所有的正常化后的 PNG 图片

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])

BOOL saveImage(NSImage *image, NSString *path);

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        if (argc < 2) {
            NSLog(@"请输入包含待处理的 PNG 图片的路径");
            return 0;
        }

        NSString *fileRootPath = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];

        NSURL *diskCacheURL = [NSURL fileURLWithPath:fileRootPath isDirectory:YES];
        NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLNameKey];

        // This enumerator prefetches useful properties for our cache files.
        NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:diskCacheURL
                                                                     includingPropertiesForKeys:resourceKeys
                                                                                        options:NSDirectoryEnumerationSkipsHiddenFiles
                                                                        errorHandler:NULL];

        NSString *decodeFileRootPath = [fileRootPath stringByAppendingPathComponent:@"decode"];

        [[NSFileManager defaultManager] createDirectoryAtPath:decodeFileRootPath
                                  withIntermediateDirectories:YES
                                                   attributes:nil
                                                        error:NULL];
        // 统计 png 图片
        NSMutableArray *allFiles = [NSMutableArray array];
        for (NSURL *fileURL in fileEnumerator) {

            NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];

            if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
                continue;
            }
            NSString *fileName = resourceValues[NSURLNameKey];
            if (![[fileName pathExtension] isEqualToString:@"png"]) {
                continue;
            }
            [allFiles addObject:fileName];
        }
        NSLog(@"共有 %zd 张 PNG 图片", allFiles.count);

        NSUInteger count = 0;
        for (NSString *fileName in allFiles) {
            NSString *originFilePath = [fileRootPath stringByAppendingPathComponent:fileName];
            NSString *decodeFilePath = [decodeFileRootPath stringByAppendingPathComponent:fileName];
            NSImage *image = [[NSImage alloc] initWithContentsOfFile:originFilePath];
            if (saveImage(image, decodeFilePath)) {
                ++count;
                NSLog(@"进度 - %.2f%%", 100.0 * count / allFiles.count);
            }
        }

        NSLog(@"共转换 %zd 张图片", count);
    }
    return 0;
}

BOOL saveImage(NSImage *image, NSString *path) {

    [image lockFocus];
    NSBitmapImageRep *bits = [[NSBitmapImageRep alloc]initWithFocusedViewRect:NSMakeRect(0, 0, image.size.width, image.size.height)];
    [image unlockFocus];

    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];

    NSData *imageData = [bits representationUsingType:NSPNGFileType properties:imageProps];

    return [imageData writeToFile:path atomically:YES];
}

完善

  • 同时集成正常化和压缩处理, 新建一个 shell 脚本文件(如 pngNormalizer.sh), 加入如下代码
# /bin/bash

ipaPNGnormalizer ./
zip -r decode decode/
  • 将这个脚本文件放入包含需要正常化的 PNG 的文件中, 然后在终端输入如下命令
./pngNormalizer.sh
  • 至此任务完成, 将 decode.zip 拷给其他小伙伴就可以了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值