CGImage没有属性/元数据(CGImageProperties)。

huangapple go评论88阅读模式
英文:

CGImage has no properties / metadata (CGImageProperties)

问题

假设我有一个从某个URL加载的CGImage,并且我想通过CGImageSourceCopyPropertiesAtIndex提取其属性:

// Playground

import SwiftUI

func printPropertiesOf(_ image: CGImage) {
    guard let dataProvider = image.dataProvider else {
        print("无法获取数据提供程序。")
        return
    }
    guard let data = dataProvider.data else {
        print("无法获取数据。")
        return
    }
    guard let source = CGImageSourceCreateWithData(data, nil) else {
        print("无法获取源。")
        return
    }
    guard let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) else {
        print("无法获取属性。")
        return
    }
    print(properties)
}

let url = Bundle.main.url(forResource: "Landscape/Landscape_0", withExtension: "jpg")!
let source = CGImageSourceCreateWithURL(url as CFURL, nil)!
let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil)!

printPropertiesOf(cgImage)

输出:

无法获取属性。


但是,如果我使用图像所在的URL,而不是CGImage

// Playground

import SwiftUI

func printPropertiesOfImageIn(_ url: URL) {
    guard let data = try? Data(contentsOf: url) else {
        print("无法获取数据。")
        return
    }
    guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
        print("无法获取源。")
        return
    }
    guard let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) else {
        print("无法获取属性。")
        return
    }
    print(properties)
}

let url = Bundle.main.url(forResource: "Landscape/Landscape_0", withExtension: "jpg")!

printPropertiesOfImageIn(url)

输出:

{
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    PixelHeight = 1200;
    PixelWidth = 1800;
    "JFIF" =     {
        DensityUnit = 1;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 72;
        YDensity = 72;
    };
    "TIFF" =     {
        Orientation = 0;
        ResolutionUnit = 2;
        XResolution = 72;
        YResolution = 72;
    };
}

有没有一种方法可以从CGImage本身检索元数据,而不必依赖于其源URL?

如果没有,是否有一种方法可以找出给定CGImage的源URL

(注意:上面示例中使用的图像可以在此处找到。)

英文:

Say I have a CGImage that was loaded from some URL, and I want to extract its properties via CGImageSourceCopyPropertiesAtIndex:

// Playground

import SwiftUI

func printPropertiesOf(_ image: CGImage) {
    guard let dataProvider = image.dataProvider else {
        print("Couldn't get the data provider.")
        return
    }
    guard let data = dataProvider.data else {
        print("Couldn't get the data.")
        return
    }
    guard let source = CGImageSourceCreateWithData(data, nil) else {
        print("Couldn't get the source.")
        return
    }
    guard let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) else {
        print("Couldn't get the properties.")
        return
    }
    print(properties)
}

let url = Bundle.main.url(forResource: "Landscape/Landscape_0", withExtension: "jpg")!
let source = CGImageSourceCreateWithURL(url as CFURL, nil)!
let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil)!

printPropertiesOf(cgImage)

Output:

> Couldn't get the properties.


But if I use the URL where the image resides, instead of the CGImage:

// Playground

import SwiftUI

func printPropertiesOfImageIn(_ url: URL) {
    guard let data = try? Data(contentsOf: url) else {
        print("Couldn't get the data.")
        return
    }
    guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
        print("Couldn't get the source.")
        return
    }
    guard let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) else {
        print("Couldn't get the properties.")
        return
    }
    print(properties)
}

let url = Bundle.main.url(forResource: "Landscape/Landscape_0", withExtension: "jpg")!
let source = CGImageSourceCreateWithURL(url as CFURL, nil)!
let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil)!

printPropertiesOfImageIn(url)

Output:

{
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    PixelHeight = 1200;
    PixelWidth = 1800;
    "{JFIF}" =     {
        DensityUnit = 1;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 72;
        YDensity = 72;
    };
    "{TIFF}" =     {
        Orientation = 0;
        ResolutionUnit = 2;
        XResolution = 72;
        YResolution = 72;
    };
}


> Is there a way to retrieve the metadata from a CGImage itself,
> without having to rely on its source URL?
>
> If not, is there a way to find out the source URL of a given
> CGImage?

(Note: the image used in the above examples can be found here.)

答案1

得分: 3

CGImage 应该是完全未经处理的位图数据。至少需要一组未压缩的数据来视觉呈现图像。来自文档:"位图图像或图像掩码"。

我实际上很惊讶您能够以两种如此不同的方式构建源使用 CGImageSourceCreateWithData

  • 在第一种情况下,您直接从原始未压缩数据创建它,这是您的 CGImage。预期它绝对没有头部或关于如何显示它的附加信息。

  • 在第二种情况下,您从JPEG数据创建它,这是带有可能包含许多不同信息的头部的压缩数据。其中一些信息可能完全不相关,例如图像拍摄位置的坐标或拍摄日期。

因此,在第二种情况下显示的附加信息可能会被系统用于构建 CGImage 对象(例如编码)。但这不是需要附加到 CGImage 以显示它的信息,因为它已经准备好(解码)以供呈现。

在您的标题中,您说“CGImage 没有属性/元数据(CGImageProperties)”。不存在“CGImageProperties”,存在“CGImageSourceProperties”。因此,属性是存在于源中的。

因此,我认为这些属性不会被复制,也没有办法仅从 CGImage 获取它们。但您可以直接从 CGImage 获取其他属性:

  • cgImage.width
  • cgImage.height
  • cgImage.alphaInfo
  • cgImage.bitmapInfo
  • cgImage.bitsPerComponent
  • cgImage.colorSpace
  • ...

您可以在此处进一步查看。

英文:

The CGImage should be completely raw bitmap data. A minimum set of uncompressed data to visually present an image even. From docs "A bitmap image or image mask".

I am actually surprised that you were able to construct a source using CGImageSourceCreateWithData in two such different ways:

  • In first case you are creating it directly from raw uncompressed data which is your CGImage. It is expected that it has absolutely no headers or additional information on how it should be shown.

  • In second case you are creating it from JPEG data which is compressed data with headers that may contain a lot of different information. Some of the info may be completely unrelated such as coordinates of where image was taken or date it was taken on for instance.

So the additional information that you are showing in second case could potentially be used by the system to construct a CGImage object (encoding for instance). But it is not the information that needs to be appended to CGImage in order to display it since it is already prepared (decoded) for presentation.

In your title you are saying "CGImage has no properties / metadata (CGImageProperties)". There is no such thing as "CGImageProperties", there is "CGImageSourceProperties". So it is the source that has the properties.

So I believe these properties are not copied and there is no way to get them from CGImage alone. There are other properties you can get directly from CGImage though:

  • cgImage.width
  • cgImage.height
  • cgImage.alphaInfo
  • cgImage.bitmapInfo
  • cgImage.bitsPerComponent
  • cgImage.colorSpace
  • ...

You can check a bit more here.

huangapple
  • 本文由 发表于 2020年1月6日 21:08:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定