【问题标题】:When should I use UIImageJPEGRepresentation and UIImagePNGRepresentation for uploading different image formats to the server?何时应该使用 UIImageJPEGRepresentation 和 UIImagePNGRepresentation 将不同的图像格式上传到服务器?
【发布时间】:2013-07-02 18:15:07
【问题描述】:

在我的应用程序中,我必须将不同格式的图像发送到服务器(必须是UIImage 类可以读取的所有文件格式)https://developer.apple.com/library/ios/#documentation/uikit/reference/UIImage_Class/Reference/Reference.html

问题是:我不知道什么时候应该使用这些方法。当然很明显,对于.png 图像我需要使用UIImagePNGRepresentation.jpg/.jpeg UIImageJPEGRepresentation。但是其他格式(.tiff.gif 等)呢?图像处理只有两种方法,格式很多。

【问题讨论】:

    标签: ios objective-c cocoa-touch uiimage uikit


    【解决方案1】:

    你说:

    当然,对于 .png 图像,我需要使用 UIImagePNGRepresentation,对于 .jpg/.jpeg,我需要使用 UIImageJPEGRepresentation

    不,不一定是这样。如果您有一些原始“数字资产”,而不是创建UIImage,然后使用这两个函数之一创建您将上传的NSData,您通常只需从原始资产加载NSData并完全绕过UIImage 的往返。如果您这样做,则不会冒任何数据丢失的风险,因为转换为 UIImage,然后再返回可能会导致。

    不过,还有一些额外的注意事项:

    1. 元数据:

      这些UIImageXXXRepresentation 函数会剥离其元数据的图像。有时这是一件好事(例如,您不想上传您孩子的照片或昂贵的小工具,包括 GPS 位置,不满者可以识别拍摄地点)。在其他情况下,您不希望元数据被丢弃(例如原始拍摄的日期、哪个相机等)。

      您应该明确决定是否要剥离元数据。如果不是,请不要通过UIImage 来回传输您的图像,而是使用原始资产。

    2. 图像质量损失和/或文件大小注意事项:

      我特别不喜欢UIImageJPEGRepresentation,因为它是lossy compression。因此,如果您使用小于 1.0 的 compressionQuality 值,您可能会损失一些图像质量(接近 1.0 的值会造成适度的质量损失,compressionQuality 值越低则质量损失越大)。如果您使用 1.0 的 compressionQuality,则可以减轻大部分 JPEG 图像质量损失,但生成的 NSData 通常可能比原始资源大(至少如果原始资源本身是压缩的 JPEG 或 PNG ),导致上传速度变慢。

      UIImagePNGRepresentation 不会引入基于压缩的数据丢失,但根据图像,您仍然可能丢失数据(例如,如果原始文件是 48 位 TIFF 或使用 sRGB 以外的颜色空间)。

      这是一个问题,您是否可以在上传过程中出现一些图像质量损失和/或较大的文件大小。

    3. 图片尺寸:

      有时您不想上传全分辨率图片。例如,您可能正在使用希望图像每边不大于 800 像素的 Web 服务。或者,如果您要上传缩略图,他们可能想要更小的东西(例如 32 像素 x 32 像素)。通过调整图像大小,您可以使上传更小,从而更快(尽管有明显的质量损失)。但是,如果您使用image resizing algorithm,那么使用这些UIImageXXXRepresentation 函数创建PNG 或JPEG 会很常见。

    简而言之,如果我想尽量减少数据/质量损失,我会上传原始资产(如果它是服务器接受的格式),我会使用 UIImagePNGRepresentation(或 UIImageJPGRepresentation 和质量如果原始资产不是服务器接受的格式,则设置为 1.0)。但是选择使用这些UIImageXXXRepresentation 函数是您的业务需求和服务器接受什么的问题。

    【讨论】:

    • 有哪些方法可以将原始资产转换为等效的 NSData,而不使用其中任何一种方法?
    • @JeremyHicks 这取决于原始资产是什么。如果是imageWithContentsOfFile,则返回该文件。如果是imageWithContentsOfURL,您应该从该 URL 获取它(或者更准确地说,从该 URL 获取 NSData,然后使用 imageWithData 生成 UIImage,但请参考原始的 @987654347 @ 获取原始资产)。如果它来自ALAssetsLibrary,则使用assetForURL 获取ALAsset,然后使用getBytes 检索与原始资产关联的数据。这完全取决于您如何获得原始资产。
    • 有时您必须使用UIImageXXXRepresentation 函数(例如,它是动态创建/修改图像的快照)并忍受强加的限制,但如果您有权访问原始资产,则应该如果可以,请回到那个位置。
    【解决方案2】:

    Rob 指出了在处理图像时需要考虑的许多非常好的事情 (+1),但是这里有一个示例,说明如何按照您的要求创建 tiff 和 gif:

    首先,您需要链接到ImageIO 库(在应用的构建阶段下)。

    接下来你需要在文件顶部#import <ImageIO/ImageIO.h>

    然后,以下代码将为您转换图像:

    // Get a reference to the image that you already have stored on disk somehow.
    // If it isn't stored on disk, then you can use CGImageSourceCreateWithData() to create it from an NSData representation of your image.
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"01" withExtension:@"jpg"];
    CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)(url), NULL);
    
    // Create a URL referencing the Application Support Directory.  We will save the new image there.
    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *suppurl = [fm URLForDirectory:NSApplicationSupportDirectory
                                inDomain:NSUserDomainMask
                       appropriateForURL:nil
                                  create:YES
                                   error:NULL];
    
    // Append the name of the output file to the app support directory
    // For tiff change the extension in the next line to .tiff
    NSURL *gifURL = [suppurl URLByAppendingPathComponent:@"mytiff.gif"];
    
    // Create the destination for the new image
    // For tiff, use @"public.tiff" for the second argument of the next line (instead of @com.compuserve.gif".
    CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)gifURL,
                                                                 (CFStringRef)@"com.compuserve.gif",
                                                                 1,
                                                                 NULL);
    CGImageDestinationAddImageFromSource(dest, src, 0, NULL);
    
    // Write the image data to the URL.
    bool ok = CGImageDestinationFinalize(dest);
    if (!ok)
        NSLog(@"Unable to create gif file.");
    
    // Cleanup
    CFRelease(src);
    CFRelease(dest);
    

    这是改编自this book中的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-04
      • 2013-03-09
      • 2011-08-23
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多