NSBitmapImageRep.bitmapImageRepByConvertingToColorSpace()调用不推荐使用的CGContextClear

时间:2014-12-18 14:21:58

标签: macos opengl

我正在尝试使用

NSBitmapImageRep.bitmapImageRepByConvertingToColorSpace(NSColorSpace.genericRGBColorSpace(), renderingIntent: NSColorRenderingIntent.Perceptual);

将NSImage转换为可以由openGL处理​​的格式,并且它可以工作(与bitmapImageRepByRetaggingWithColorSpace()不同),但是我收到错误:

<Error>: The function ‘CGContextClear’ is obsolete and will be removed in an upcoming update. Unfortunately, this application, or a library it uses, is using this obsolete function, and is thereby contributing to an overall degradation of system performance.

这有点无用,因为它是Apple自己的代码,我似乎无法找到bitmapImageRepByConvertingToColorSpace()的替代品,或者它也被弃用的任何注释。

编辑:

                var image=NSImage(size: frame);
                image.lockFocus();
                //println("NSImage: \(image.representations)");
                string.drawAtPoint(NSMakePoint(0.0,0.0), withAttributes: attribs);
                var bitmap2=NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0,0.0,frame.width,frame.height))?;
                image.unlockFocus();
                    bitmap=bitmap2!.bitmapImageRepByConvertingToColorSpace(NSColorSpace.genericRGBColorSpace(), renderingIntent: NSColorRenderingIntent.Perceptual);

3 个答案:

答案 0 :(得分:0)

出于某种原因,这个问题让我很感兴趣。看起来解决方案是将焦点锁定在NSImage上,然后使用NSBitmapImageRep(focusedViewRect :)来创建NSBitmapImageRep。

我尝试重新创建你的情况(据我所知),然后使用以下代码创建一个NSBitmapImageRep:

var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()

let testString:NSString = "test String"
testString.drawAtPoint(NSMakePoint(10,10), withAttributes: nil)

img.unlockFocus()

println("img Description = \(img.description)")

我得到了以下描述:

img描述= NSImage 0x608000067ac0大小= {200,200} Reps =(     “NSCGImageSnapshotRep:0x61000007cf40 cgImage = CGImage 0x6100001a2bc0”)

然后我将此代码扩展为:

var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()

let testString:NSString = "test String"
testString.drawAtPoint(NSMakePoint(10,10), withAttributes: nil)

img.unlockFocus()

println("img Description = \(img.description)")

img.lockFocus()

var bitmapRep:NSBitmapImageRep = NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0, 0.0, img.size.width, img.size.height))!

img.unlockFocus()

println("bitmap data planes = \(bitmapRep.bitmapData)")
println("bitmap pixels wide = \(bitmapRep.size.width)")
println("bitmap pixels high = \(bitmapRep.size.height)")
println("bits per sample = \(bitmapRep.bitsPerSample)")
println("samples per pixel = \(bitmapRep.samplesPerPixel)")
println("has alpha = \(bitmapRep.alpha)")
println("is planar = \(bitmapRep.planar)")
println("color space name = \(bitmapRep.colorSpace)")
println("bitmap format = \(bitmapRep.bitmapFormat)")
println("bytes per row = \(bitmapRep.bytesPerRow)")
println("bits per pixel = \(bitmapRep.bitsPerPixel)")

NSBitmapImageRep参数的输出为:

位图数据平面= 0x000000010b6ff100

位图像素宽= 200.0

位图像素高= 200.0

每个样本的

位= 8

每像素的样本= 4

有alpha = true

是plane = false

颜色空间名称=颜色LCD颜色空间

位图格式= C.NSBitmapFormat

每行

个字节= 800

每像素位数= 32

答案 1 :(得分:0)

我在下面发布了一些新代码。我创建了两个NSBitMapImageRep,就像你的代码一样(除了我使用方法bitmapImageRepByRetaggingWithColorSpace),我将它们都导出到PNG文件中。我在两个PNG文件中都获得了相同的图像。

但我想知道几件事。首先,两个测试的不同之处不仅在于OS X版本,而且硬件产生了不同的颜色空间。您应该检查以确保bitmap2不是nil。

其次,我想知道OpenGL是否关心。如果bitmap2不是nil并且您传递OpenGL bitmap2.bitmapData,它是否有效?

我的新代码(删除大部分println):

var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()

let testString:NSString = "test String"
let font:NSFont = NSFont(name: "AppleCasual", size: 18.0)!
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as NSMutableParagraphStyle
textStyle.alignment = NSTextAlignment.LeftTextAlignment
let textColor:NSColor = NSColor(calibratedRed: 1.0, green: 0.0, blue: 1.0, alpha: 1.0)

let attribs:NSDictionary = [NSFontAttributeName: font,
        NSForegroundColorAttributeName: textColor,
        NSParagraphStyleAttributeName: textStyle]

testString.drawAtPoint(NSMakePoint(0.0, 0.0), withAttributes: attribs)

img.unlockFocus()

println("img Description = \(img.description)")

img.lockFocus()

var bitmapRep:NSBitmapImageRep = NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0, 0.0, img.size.width, img.size.height))!

img.unlockFocus()

let pngPath:String = "TestStringBeforeChange.png"

let imageProps = [NSImageCompressionFactor: NSNumber(float: 1.0)]
let outputImageData = bitmapRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: imageProps)

let fileSavePanel = NSSavePanel()
fileSavePanel.nameFieldStringValue = pngPath

var savePanelReturn = fileSavePanel.runModal()

if savePanelReturn == NSFileHandlingPanelOKButton
{
    var theFileURL = fileSavePanel.URL
    var saveStatus = outputImageData?.writeToURL(theFileURL!, atomically: true)
}

let bitmapRep2 = bitmapRep.bitmapImageRepByRetaggingWithColorSpace(NSColorSpace.genericRGBColorSpace())

let pngPath2:String = "TestStringAfterChange.png"
let outputImageData2 = bitmapRep2!.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: imageProps)

let fileSavePanel2 = NSSavePanel()
fileSavePanel2.nameFieldStringValue = pngPath2

var savePanel2Return = fileSavePanel2.runModal()

if savePanel2Return == NSFileHandlingPanelOKButton
{
    var theFileURL2 = fileSavePanel2.URL
    var saveStatus2 = outputImageData2?.writeToURL(theFileURL2!, atomically: true)
}

答案 2 :(得分:0)

很抱歉所有帖子,但我不想放手,这很有意思。

我创建了3个PNG文件:第一个使用原始NSBitmapImageRep,第二个使用使用bitmapImageRepByRetaggingWithColorSpace创建的NSBitmapImageRep,第三个使用使用bitmapImageRepByConvertingToColorSpace创建的NSBitmapImageRep(当然,我在使用此功能时收到系统警告)。

在预览的Inspector中查看这三个PNG文件,它们都是RGB颜色模型;只有第一个文件的colorSynch配置文件与第二个和第三个文件的配置文件不同。所以我想也许这些文件中的bitmapData没有区别。

然后我写了一些代码来比较bitmapData:

var firstRepPointer:UnsafeMutablePointer<UInt8> = bitmapRep.bitmapData
var secondRepPointer:UnsafeMutablePointer<UInt8> = bitmapRep2!.bitmapData
var firstByte:UInt8 = 0
var secondByte:UInt8 = 0

for var i:Int = 0; i < 200; i++
{
    for var j:Int = 0; j < 200; j++
    {
        for var k:Int = 0; k < 4; k++
        {
            memcpy(&firstByte, firstRepPointer, 1)
            firstRepPointer += 1
            memcpy(&secondByte, secondRepPointer, 1)
            secondRepPointer += 1

            if firstByte != secondByte {println("firstByte = \(firstByte) secondByte = \(secondByte)")}
        }
    }
}

正如我所料,当我将原始位图代表中的bitmapData与使用bitmapImageRepByRetaggingWithColorSpace创建的位图代表中的bitmapData进行比较时,没有任何差异。

然而,当我将原始位图代表中的bitmapData与使用bitmapImageRepByConvertingToColorSpace创建的位图代表的数据进行比较时,它变得更加有趣。

数据存在很多差异。差异很小,但很多。

即使我在PNG文件中看不到任何差异,底层数据也已被bitmapImageRepByConvertingToColorSpace更改。

所有这一切,我认为你应该能够将来自任何这些位图代表的.bitmapData传递给OpenGL纹理。使用bitmapImageRepByConvertingToColorSpace创建的位图代表的数据可能会创建看起来不同的纹理,但它应该是有效的数据。