【问题标题】:Converting between multiple image formats in Objective-C在 Objective-C 中的多种图像格式之间转换
【发布时间】:2011-09-27 13:53:22
【问题描述】:

我希望能够在获得图像路径的情况下将该图像转换为另一个图像,但格式不同。格式是指 .png、.bmp .jpg .tiff 等。在伪代码中,这真的很简单:

image = [ImageAPI open: imagePath]
[image save: imagePath withFormat: IMAGEFORMAT] // this is important

不过,我不知道该怎么做。在处理图像方面,我几乎不知道 NSImage 类),这似乎没有解决我的问题(没有像这样的简单保存方法)。以下是我希望支持的格式列表:

  • .png
  • .tiff
  • .gif
  • .jpeg
  • .bmp
  • 可能是 .pdf(如果不是很复杂的话)

我所说的支持是指打开其中的任何一个并将打开的图像保存为任何这些格式。这里有一些组合(15 ??? - 我认为),所以我可以为每个组合编写一个方法,如下所示:

[self saveTiffImageIntoGifWithPath: path] (*15 !!!)

但使用 API 肯定更好。

如果在此过程中我也有这样的选择:

  • 是否保留 Alpha 版
  • 调整图片大小

...我也很乐意支持它们,尽管它们是可选的。 我真的希望有一个简单的方法来做到这一点。谢谢

PS:我知道有关于这个主题的问题,但它们都是面向 iPhone 的(我想在 mac 上做这个),而且没有一个提供一种方法来处理多种格式。

【问题讨论】:

    标签: objective-c cocoa image macos image-conversion


    【解决方案1】:

    好的,所以在彼得的帮助下,我可以解决这个问题。首先,如果您正在使用图像路径,则直接使用 NSData 打开文件,如下所示:

    NSData* imgData = [NSData dataWithContentsOfFile: filePath];
    

    如果您正在使用 NSImage 对象并且很难获得路径(例如使用 NSImageView),那么请执行此操作(图像是您拥有的 NSImage 对象):

    NSData* imgData = [image TIFFRepresentation];
    

    现在您已将图像放入 NSData 对象,将其放入 NSBitmapImageRep:

    NSBitmapImageRep* bitmap = [NSBitmapImageRep imageRepWithData: imgData];
    

    然后得到一个新的 NSData 对象,但格式不同:

    NSData* newData = [bitmap representationUsingType: NSPNGFileType properties: nil];
    // I used NSPNGFileType as an example, but all the
    // types I wanted to convert between (except PDF) are supported
    

    最后,将 newData 保存到文件中:

    [newData writeToFile: newPath atomically: YES]
    

    简单易懂,一旦你了解它的工作原理!


    对透明度和大小控制的支持也不是那么困难:

    • NSImage 类支持设置图像的大小 (-setSize:)
    • NSImageRep(NSBitmapImageRep 的超类)具有 -setAlpha: 方法

    只需在需要时致电。 +1 可可!

    【讨论】:

    • 这做了很多不必要的工作。您无需将文件导出到 TIFF 即可将其导出为 PNG。当你有一个文件的路径或文件内容的数据时,创建一个 NSBitmapImageRep 是一个步骤,然后你可以直接从中创建 PNG 数据。
    • @peter 是的,我知道。但想象一下我正在使用 NSImageView。它没有给你路径,只有 NSImage 对象,所以在这种情况下,你需要将 NSImage 转换为 NSData,这是我找到的唯一方法。否则,当然!不要使用 NSImage,就像你说的那样用 NSData 打开。
    • 或者直接从文件中,当你有路径时。如果你曾经有过一条路,为什么不保留它呢?您不应该将模型存储在视图中;您将其传递给视图仅供视图使用。您的控制器应始终保持原始图像的路径。如果这是一个基于文档的应用程序,它无论如何都会这样做;如果没有,您将不得不并且应该自己这样做。
    【解决方案2】:

    NSImage 向外探索会带你到NSBitmapImageRep,这正是你想要的。

    其中一些 iPhone 问题也是相关的,因为适用于两个平台的解决方案(以及当今 NSBitmapImageRep 解决方案背后的实现)是使用CGImageSource 读取图像并使用CGImageDestination 将其写出.

    【讨论】:

    • 好吧,NSBitmapImageRep 似乎进行了转换(representationUsingType:properties:),但我真的不明白如何保存图像!我使用 NSImage 加载图像,使用 [NSBitmapImageRep representationUsingType:properties:] 添加表示,然后呢?!?没有像saveImageToPath 这样的保存方法。我一定遗漏了一些非常明显的东西......
    • 哦...我想这次我明白了。请检查:我使用 NSData 打开原始图像,将数据传递到[NSBitmapImageRep initWithData:],调用[NSBitmapImageRep representationUsingType:properties:],然后将结果数据写入文件。瞧!是这个吗?最好是这样,否则我会很困惑。我现在无法测试它,所以这就是我问的原因。 PS:如果是这样,那么解决方案真的很明显...... :)
    • @Alex Truppel:是的,尽管 NSBitmapImageRep 确实允许您直接从文件的内容创建一个。 (不要忘记查看超类!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多