2010-07-15 5 views

Répondre

2
CGImageRef CGImageCreateCopyWithColorSpace (
    CGImageRef image, 
    CGColorSpaceRef colorspace 
); 

Pour obtenir un CGColorSpaceRef, vous pouvez faire des choses comme

CGColorSpaceRef CGColorSpaceCreateDeviceRGB(); 

OU voir this page pour savoir comment créer d'autres espaces de couleurs.

+0

Hmm. J'ai essayé cela et cela n'a pas fonctionné quand j'ai essayé d'utiliser un espace de couleurs GrayScale. –

+0

C'est une bonne chose à savoir, mais pas une réponse à la question. La question était sur la façon de changer l'espace de couleur d'une image, pas comment créer un espace de couleur. – danpalmer

+2

J'ai répondu à la question. La première fonction que j'ai posté était comment créer une nouvelle image dans un espace de couleur spécifique. L'idée est de créer vous-même un espace de couleur pour l'espace colorimétrique souhaité, puis d'utiliser 'CGImageCreateCopyWithColorSpace()' pour créer une nouvelle copie de votre image dans le nouvel espace colorimétrique. –

3

Le problème avec le code que vous voyez ci-dessous

CGImageRef CGImageCreateCopyWithColorSpace (
CGImageRef image, 
CGColorSpaceRef colorspace 
); 

ne fonctionne pas parce que Quartz2D ne prend pas en charge alpha pour les images CMJN ou des images grises, il est pris en charge uniquement par des images RVB. Ce que vous devez faire est de créer 2 images puis de les combiner dans le cas d'un espace colorimétrique CMJN et d'une image avec alpha. J'ai beaucoup cherché sur ce sujet et finalement trouvé. Peut être l'auteur de cette question n'en a plus besoin mais quelqu'un d'autre peut en avoir besoin.

  1. Créer un nouveau 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. Vous devez dessiner votre image dans le nouveau bitmap permet de dire que vous avez 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. Après cela, vous aurez une imageRep que est l'image avec l'espace de couleur correct mais pas d'alpha (transparence).

  4. Vous avez besoin d'un bitmap de masque. Obtenir un masque est difficile.

    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. Clip image blanche à votre image avec transparence

    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. coloriser tous pixel en couleur blanche, ce sera coupé à l'image.

    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. À cette étape, vous disposez d'une image et d'un masque. Ensuite, nous devons les combiner. J'utilise ce petit algorithme (vous devez vérifier que l'image de masque et la source ont de même taille et même 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 Bonjour les amis, que diriez-vous si je veux créer une image grise au lieu d'un CYMK? Ai-je encore besoin de créer un masque alpha? Mais il ne semble pas logique pour une image greyscaled d'avoir un canal alpha .. J'ai essayé simple sans faire un masque, mais il renvoie une image noire .. Ou, devrais-je simplement simplement accéder à et prendre la moyenne des canaux de couleur ? – user3390652

+0

@ user3390652 "Ou, est-ce que je devrais simplement accéder à et prendre la moyenne des canaux de couleur?" Je pense que c'est une très bonne option! (n'y pensait pas vraiment, mais probablement seulement la moyenne des canaux RVB et laisse l'alpha tel quel). – HAS

+0

@HAS Au fait, pourriez-vous donner un exemple de votre deuxième étape ci-dessus s'il vous plaît? '// fais ton dessin ici' j'ai essayé, avec une' image NSImage', 'image.representation.first.draw()' ... Il semble que ça marche seulement avec un 'focus de verrouillage' mais pas un 'état graphique' . C'est pourquoi je me bats pourquoi j'ai une image vide avec tous les pixels sont des zéros (j'ai chargé l'image dans MATLAB et l'ai trouvé ..) .. – user3390652