来自Swift中CGImage的RGB数据

时间:2014-07-18 16:53:27

标签: macos pointers swift core-graphics

我试图在Swift中构建阅读RGB pixel data。 获取基本的图像信息没有问题,但我认为我的指针和字节偏移有问题:

let provider:CGDataProviderRef = CGImageGetDataProvider(inImage)
let data:NSData = CGDataProviderCopyData(provider)
let bytes: COpaquePointer = data.bytes // Needs to be changed to ConstUnsafePointer<()> in xCode beta3
let bytePointer = UnsafePointer<UInt8>(bytes)

println("Pixel Data:\n")

var printString:String = ""

    for var row:Int = 0; row < Int(height); row++ {
    for var col:Int = 0; col < Int(width); col++ {

        var pixel:UInt8 = bytePointer[row * Int(bytesPerRow) + col * Int(bytesPerPixel)]
        printString += "("

        for var x = 0; x < Int(bitsPerPixel); x++ {
            printString += pixel[x]
        }

        printString += ")"

        if col < Int(width) - 1 {
            printString += ","
        }

    }
    printString += "\n"
}

println(printString)

(我将Int转换为变量bytesPerRow等,因为它们是UInt8)

我得到了一个4x2px图像,其中包含两行以下像素:红色,绿色,蓝色,白色。所以我希望这个输出(没有alpha):

(ff0000), (00ff00), (0000ff), (ffffff)
(ff0000), (00ff00), (0000ff), (ffffff)

printString += pixel[x]

进行编译时出错
  

'UInt8'没有名为'下标'的成员

我认为它可以只是附加到swift中的字符串。我试图将它转换为字符串,但这也不起作用。所以也许我对指针做错了。

如何获得正确的输出?

修改

我认为@David让我走上正轨。但是在第一个8字节之后发生了奇怪的事情。这可能是@ heinrich-giesen建议填充的吗?

3次测试的原始图像数据如下所示:

Pic1: 3Byte/Pixel, no Alpha, 4 pixelWidth, 2 pixelHeight, [red, green, blue white; red, green, blue white]
Raw Data: <ff000000 ff000000 ffffffff ff000000 ff000000 ffffffff>

Pic2: 4Byte/Pixel, Alpha, 4 pixelWidth, 2 pixelHeight, [red, green, blue white (alpha); red, green, blue white]
Raw Data: <ff000000 00ff0000 0000ff00 ffffff00 ff0000ff 00ff00ff 0000ffff ffffffff>

如果你看一下原始数据,我很清楚我希望输出如下:

Pic1
(ff,00,00), (00,ff,00), (00,00,ff), (ff,ff,ff)
(ff,00,00), (00,ff,00), (00,00,ff), (ff,ff,ff)

Pic2
(ff,00,00,00), (00,ff,00,00), (00,00,ff,00), (ff,ff,ff,00)
(ff,00,00,ff), (00,ff,00,ff), (00,00,ff,ff), (ff,ff,ff,ff)

但我的代码生成的实际输出是:

Pic1   
((ff, 00, 00, ), (00, 00, ff, ), (00, ff, ff, ), (ff, ff, 00, ))
((ff, 00, 00, ), (00, 00, ff, ), (00, ff, 00, ), (ff, 00, 00, ))

Pic2 
((ff, 00, 00, ff, ), (00, 00, ff, ff, ), (00, ff, ff, 00, ), (ff, ff, 00, 00, )) 
((ff, 00, 00, ff, ), (00, 00, ff, 00, ), (00, ff, 00, 00, ), (ff, 00, 00, 00, ))

现在构建输出的代码是:

    for var row:Int = 0; row < Int(height) ; row++ {

        printString += "("

        for var col:Int = 0; col < Int(width); col++ {

            printString += "("

            for var x = 0; x < Int(bytesPerPixel); x++ {

                var pixel:UInt8 = bytePointer[row * Int(bytesPerRow) + col * Int(bytesPerPixel) + x * Int(bytesPerPixel)]
                printString += NSString(format:"%02x, ", pixel)

            }

            printString += ")"

            if col < Int(width) - 1 {
                printString += ", "
            }

        }
        printString += ")\n"
    }

println(printString)

是否有填充(就像原始数据输出中的空格一样)?我试图在最初的8之后跳过一个和两个,但这不会产生较少混乱的输出。 8字节后出现问题。建议?

2 个答案:

答案 0 :(得分:1)

您的代码看起来有点奇怪。你确定这行:

    for var x = 0; x < Int(bitsPerPixel); x++ {

是对的吗?你的意思是bitsPerPixel而不是bytesPerPixel吗? (或samplesPerPixel或swift中的任何内容)。你确定一个组件(一个样本)有8位吗?一个像素没有填充字节?

另一点:heightwidth是什么?它们是图像size的组成部分吗?那是错的。您必须使用pixelsWidepixelsHigh。图像的size仅表示有多大 - 以英寸或厘米或(1/72)英寸(称为点)表示 - 应描绘图像。这与像素数无关。但是你在处理像素!

答案 1 :(得分:0)

将bytePointer更改为UnsafePointer<UInt32>并更新循环以使用shift(&gt;&gt;)和掩码(&amp; 0xff)访问单词的各个字节。

    var pixel:UInt32 = bytePointer[row * Int(bytesPerRow) + col * Int(bytesPerPixel)]
    printString += NSString(withFormat:"(%08x)", pixel)

那也会给你alpha通道,但是你得到漂移。