2014-02-11 16 views
5

Dieser Code kombiniert ein Bild und ein Graustufenmaskenbild in einem UII-Bild. Es funktioniert, aber es ist langsam.Wie kombiniere ich ein Bild mit einer Maske zu einem einzigen UIImage mit Accelerate Framework?

+ (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *) mask 
{ 
    CGImageRef imageReference = image.CGImage; 
    CGImageRef maskReference = mask.CGImage; 

    CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference), 
              CGImageGetHeight(maskReference), 
              CGImageGetBitsPerComponent(maskReference), 
              CGImageGetBitsPerPixel(maskReference), 
              CGImageGetBytesPerRow(maskReference), 
              CGImageGetDataProvider(maskReference), 
              NULL, // Decode is null 
              YES // Should interpolate 
              ); 

    CGImageRef maskedReference = CGImageCreateWithMask(imageReference, imageMask); 
    CGImageRelease(imageMask); 

    UIImage *maskedImage = [UIImage imageWithCGImage:maskedReference]; 
    CGImageRelease(maskedReference); 

    return maskedImage; 
} 

Ich denke, dass Accelerate Framework helfen kann. Aber ich bin mir nicht sicher. Es gibt vImage und es kann alpha compositing tun. Oder, was ich suche, heißt "vImage Transform". Nicht wie CATransform3D, aber das Bild wird "transformiert".

Aber was ich brauche, ist ein Foto in ein transparentes JPEG basierend auf einer Maske zu machen.

Kann Accelerate Framework dafür verwendet werden? Oder gibt es eine Alternative?

Antwort

2

VImageOverwriteChannels_ARGB8888 ist wahrscheinlich die API, die Sie wollen, vorausgesetzt, das Bild-JPEG ist zu Beginn undurchsichtig. Sie können vImageBuffer_InitWithCGImage verwenden, um das Quellbild als 8 bpc, 32 bpp, kCGImageAlphaNoneSkipFirst | zu extrahieren kCGBitmapByteOrder32Little. Dadurch erhalten Sie ein BGRA8888-Bild mit opakem Alpha. Holen Sie die Maske als 8bpc, 8bpp, kCGImageAlphaNone Bild heraus. Verwenden Sie vImageOverwriteChannels_ARGB8888, um den BGRA alpha mit dem neuen Alphakanal zu überschreiben. Erstellen Sie dann ein neues CGImage mit vImageCreateCGImageFromBuffer und ändern Sie das Format geringfügig in kCGImageAlphaFirst | kCGBitmapByteOrder32Little.

Sie können auch versuchen, die Maske in das Bild einzuebnen, indem Sie maskedReference oben verwenden und direkt in BGRA kCGImageAlphaFirst dekodieren. Dies funktioniert nur gut, wenn das Bild und die Maske die gleiche Größe haben. Ansonsten tritt etwas Resampling auf, was zeitaufwendig ist.

Ich weiß nicht, ob einer von diesen wirklich schneller wird oder nicht. Es wäre nützlich, ein Instrument Zeitprofil zu sehen, wo Ihre Zeit läuft. vImageOverwriteChannels_ARGB8888 ist wahrscheinlich nur ein kleiner Teil der Arbeit, die hier erledigt werden muss. Abhängig vom Format des Originalbildes kann im Hintergrund in vImageBuffer_InitWithCGImage und vImageCreateCGImageFromBuffer ziemlich viel Arbeit für die Farbraumkonvertierung und Bildformatkonvertierung entstehen. Der Schlüssel zur Geschwindigkeit hier (und mit dem konkurrierenden CG-Pfad) besteht darin, die Arbeitslast durch intelligente Entscheidungen zu minimieren.

Manchmal, wenn man etwas versucht, kann man einen Fehler gegen Apple einreichen, wenn nichts gut funktioniert. Ein trivial reproduzierbares Beispiel ist normalerweise der Schlüssel.