2010-07-15 163 views

回答

2
CGImageRef CGImageCreateCopyWithColorSpace (
    CGImageRef image, 
    CGColorSpaceRef colorspace 
); 

爲了得到一個CGColorSpaceRef,你可以做這樣的事情

CGColorSpaceRef CGColorSpaceCreateDeviceRGB(); 

或參閱this page對於如何創建其他顏色空間。

+0

嗯。我嘗試過,當我嘗試使用GrayScale色彩空間時,它不起作用。 – 2010-07-15 17:20:03

+0

這是一件好事,但不是問題的答案。問題是關於如何改變圖像的色彩空間,而不是如何創建色彩空間。 – danpalmer 2011-08-17 08:33:56

+2

我的確回答了這個問題。我發佈的第一個功能是如何在特定的色彩空間中創建新圖像。這個想法是讓自己成爲想要的色彩空間的色彩空間ref,然後使用'CGImageCreateCopyWithColorSpace()'在新的色彩空間中創建一個新的圖像副本。 – 2011-08-17 10:14:53

3

與你看到下面

CGImageRef CGImageCreateCopyWithColorSpace (
CGImageRef image, 
CGColorSpaceRef colorspace 
); 

的代碼的問題是行不通的,因爲Quartz2D不支持CMYK圖像或灰度圖像α,它僅由RGB圖像的支持。 你應該做的是創建2個圖像,然後結合CMYK色彩空間和圖像與阿爾法。我已經搜索了很多關於這個話題,並最終找到。可能是這個問題的作者不再需要它,但其他人可能需要它。

  1. 創造新NSBitmapImageRep

    let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, 
                 pixelsWide: Int(round(imageSize.width)), 
                 pixelsHigh: Int(round(imageSize.height)), 
                bitsPerSample: 8, 
               samplesPerPixel: 4, 
                 hasAlpha: false, 
                 isPlanar: false, 
                colorSpaceName: NSDeviceCMYKColorSpace, 
                bitmapFormat: NSBitmapFormat(rawValue: 0), 
                bytesPerRow: Int(round(imageSize.width) * CGFloat(4)), 
                bitsPerPixel: 0) 
    
  2. 您需要繪製圖像插入新的位圖 可以說你有colorSpace: NSColorSpace

    let context = NSGraphicsContext(bitmapImageRep: imageRep) 
    NSGraphicsContext.saveGraphicsState() 
    NSGraphicsContext.setCurrentContext(context) 
    imageRep.setProperty(NSImageColorSyncProfileData, withValue: colorSpace.ICCProfileData) 
    // Do your drawing here 
    NSGraphicsContext.restoreGraphicsState() 
    
  3. 此之後,你將有一個imageRep那是具有正確色彩空間但沒有alpha(透明度)的圖像。

  4. 您需要一個掩碼位圖。獲得面具是棘手的。

    let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, 
                 pixelsWide: Int(round(imageSize.width)), 
                 pixelsHigh: Int(round(imageSize.height)), 
                bitsPerSample: 8, 
               samplesPerPixel: 1, 
                 hasAlpha: false, 
                 isPlanar: false, 
                colorSpaceName: NSDeviceWhiteColorSpace, 
                bitmapFormat: NSBitmapFormat(rawValue: 0), 
                bytesPerRow: Int(round(imageSize.width)), 
                bitsPerPixel: 0) 
    
  5. 夾白圖像圖像與透明

    if let graphicsPort = NSGraphicsContext.currentContext()?.graphicsPort { 
        let context = unsafeBitCast(graphicsPort, CGContextRef.self) 
        let imgRect = NSRect(origin: NSPoint.zero, size: image.extent.size) 
        let ciContext = CIContext() 
        let cgImage = ciContext.createCGImage(image, fromRect: image.extent) 
        CGContextClipToMask(context, imgRect, cgImage) 
    } 
    
  6. 彩色化以白色爲主色調的所有像素,這將是裁剪圖像。

    let context = NSGraphicsContext(bitmapImageRep: imageRep) 
    NSGraphicsContext.saveGraphicsState() 
    NSGraphicsContext.setCurrentContext(context) 
    imageRep.setProperty(NSImageColorSyncProfileData, withValue: colorSpace.ICCProfileData) 
    NSColor.whiteColor().setFill() 
    NSBezierPath.fillRect(NSRect(origin: NSPoint.zero, size: imageSize)) 
    NSGraphicsContext.restoreGraphicsState() 
    
  7. 在這一步你有一個圖像和一個面具。接下來我們需要將它們合併。我使用這個小算法(你需要驗證面具和源圖像具有相同的尺寸和相同colorSpaceModel):

    func createCMYKAImageRepByApplingAlphaMask(srcImageRep: NSBitmapImageRep, alphaMaskImageRep alphaMask: NSBitmapImageRep) -> NSBitmapImageRep? { 
        if canApplyMaskRepOnImageRep(srcImageRep, maskRep: alphaMask) == false { 
         return nil 
        } 
        let alphaData = alphaMask.bitmapData 
        let srcData = srcImageRep.bitmapData 
        if let imageWithAlphaMaskRep = createEmptyCMYKABitmapImageRep(alphaMask.size) { 
         if let colorSpaceData = imageColorSpace?.ICCProfileData { 
          imageWithAlphaMaskRep.setProperty(NSImageColorSyncProfileData, withValue: colorSpaceData) 
         } 
         fillPixelsWithComponentsData(imageWithAlphaMaskRep, components: { (pixelIdx: Int) -> (UInt8, UInt8, UInt8, UInt8, UInt8) in 
          let cyan = srcData[pixelIdx * 4 + 0] 
          let magenta = srcData[pixelIdx * 4 + 1] 
          let yellow = srcData[pixelIdx * 4 + 2] 
          let black = srcData[pixelIdx * 4 + 3] 
          let alpha = alphaData[pixelIdx] 
          return (cyan, magenta, yellow, black, alpha) 
         }) 
         return imageWithAlphaMaskRep 
        } 
        return nil 
    } 
    
    func createEmptyBitmapImageRep() -> NSBitmapImageRep? { 
        let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, 
                  pixelsWide: Int(round(imageSize.width)), 
                  pixelsHigh: Int(round(imageSize.height)), 
                 bitsPerSample: 8, 
                samplesPerPixel: 5, 
                  hasAlpha: true, 
                  isPlanar: false, 
                 colorSpaceName: NSDeviceCMYKColorSpace, 
                 bitmapFormat: NSBitmapFormat(rawValue: 0), 
                 bytesPerRow: Int(round(imageSize.width) * CGFloat(5)), 
                 bitsPerPixel: 0) 
        return imageRep 
    } 
    
    private func fillPixelsWithComponentsData(imgRep: NSBitmapImageRep, 
    components: (Int) -> (cyan:UInt8, magenta:UInt8, yellow:UInt8, black:UInt8, alpha:UInt8)) { 
        let imageRawData = imgRep.bitmapData 
        let imageWidth = Int(imgRep.size.width) 
        let imageHeight = Int(imgRep.size.height) 
        for pixelIdx in 0 ..< (imageWidth * imageHeight) { 
         let (cyan, magenta, yellow, black, alpha) = components(pixelIdx) 
         let fAlpha = Float(alpha)/255 
         imageRawData[pixelIdx * 5 + 0] = UInt8(Float(cyan) * fAlpha) 
         imageRawData[pixelIdx * 5 + 1] = UInt8(Float(magenta) * fAlpha) 
         imageRawData[pixelIdx * 5 + 2] = UInt8(Float(yellow) * fAlpha) 
         imageRawData[pixelIdx * 5 + 3] = UInt8(Float(black) * fAlpha) 
         imageRawData[pixelIdx * 5 + 4] = alpha 
        } 
    } 
    
+0

@HAS你好配對,如果我想創建一個灰度圖像而不是CYMK,怎麼樣?我還需要創建一個alpha蒙版嗎?但它似乎沒有道理灰色圖像有一個alpha通道..我嘗試簡單沒有做一個面具,但它返回一個黑色的圖像.. 或者,我應該只是簡單地訪問並從顏色通道平均? – user3390652 2017-02-04 19:12:54

+0

@ user3390652「或者,我應該只是簡單地訪問顏色通道並從中取平均值?」我認爲這是一個非常好的選擇! (並沒有真正考慮它,但可能只是RGB通道的平均值,並保持alpha原樣)。 – HAS 2017-02-04 19:14:45

+0

@HAS順便問一句,請介紹一下上面第二步的例子嗎? ''在這裏做你的繪圖'我試着用'NSImage image','image.representation.first.draw()'......它似乎只能在'鎖定焦點'內工作,而不是'圖形狀態' 。這是因爲我掙扎爲什麼我有一個空白的圖像,所有像素都是零(我把圖像加載到MATLAB中,發現這一點..)。 – user3390652 2017-02-04 19:29:43