2013-05-29 63 views
1

我有兩個PNG格式圖像,並且都定義了透明度。我需要將它們合併成一個新的PNG圖像,但不會丟失結果中的任何透明度。在iOS中合併兩個PNG UIImages而不會失去透明度

+(UIImage *) combineImage:(UIImage *)firstImage colorImage:(UIImage *)secondImage 
{ 
    UIGraphicsBeginImageContext(firstImage.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSaveGState(context); 

    CGContextTranslateCTM(context, 0, firstImage.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    CGRect rect = CGRectMake(0, 0, firstImage.size.width, firstImage.size.height); 
    // draw white background to preserve color of transparent pixels 
    CGContextSetBlendMode(context, kCGBlendModeDarken); 
    [[UIColor whiteColor] setFill]; 
    CGContextFillRect(context, rect); 

    CGContextSaveGState(context); 
    CGContextRestoreGState(context); 

    // draw original image 
    CGContextSetBlendMode(context, kCGBlendModeDarken); 
    CGContextDrawImage(context, rect, firstImage.CGImage); 

    // tint image (loosing alpha) - the luminosity of the original image is preserved 
    CGContextSetBlendMode(context, kCGBlendModeDarken); 
    //CGContextSetAlpha(context, .85); 
    [[UIColor colorWithPatternImage:secondImage] setFill]; 
    CGContextFillRect(context, rect); 


    CGContextSaveGState(context); 
    CGContextRestoreGState(context); 

    // mask by alpha values of original image 
    CGContextSetBlendMode(context, kCGBlendModeDestinationIn); 
    CGContextDrawImage(context, rect, firstImage.CGImage); 

    // image drawing code here 
    CGContextRestoreGState(context); 
    UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return coloredImage; 
} 

需要任何幫助來提高我的代碼的性能。

在此先感謝

回答

3

首先,在之間的那些調用CGContextSaveGStateCGContextRestoreGState,一個接一個地後一無所獲,是不是做了你什麼。 CGContextSaveGStateCGContextRestoreGState做什麼的解釋看到這個其他答案:CGContextSaveGState vs UIGraphicsPushContext

現在,它是不是100%清楚你的意思是「合併」的圖像。如果您只是想在另一個之上繪製一個,然後使用標準混合模式混合它們的顏色,那麼您只需更改這些混合模式調用即可通過kCGBlendModeNormal(或者完全不需要調用CGContextSetBlendMode。如果您想要用第一個圖像的alpha值掩蓋第二個圖像,然後你應該用正常的混合模式繪製第二個圖像,然後切換到kCGBlendModeDestinationIn並繪製第一個圖像

恐怕我不確定你的「重新嘗試使用中間的圖像着色代碼,但我的直覺是,你不會最終需要它,你應該能夠通過繪製一個圖像,然後設置混合模式,然後繪製其他圖片

A因此,您在「繪製白色背景以保留透明像素的顏色」評論下得到的代碼可能會在整個圖像中繪製白色,但它肯定不會保留透明像素的顏色,它會使這些像素變爲白色!除非你真的希望你的「透明」顏色是白色,否則你應該刪除那些代碼。

+0

由於阿隆,我去掉白色背景和它的工作對我來說着色代碼... –

0

用於維奈的問題,亞倫的評論給出的代碼來開發這個混血兒,覆蓋任意數量的圖像:

/** 
Returns the images overplayed atop each other according to their array position, with the first image being bottom-most, and the last image being top-most. 
- parameter images: The images to overlay. 
- parameter size: The size of resulting image. Any images not matching this size will show a loss in fidelity. 
*/ 
func combinedImageFromImages(images: [UIImage], withSize size: CGSize) -> UIImage 
{ 
    // Setup the graphics context (allocation, translation/scaling, size) 
    UIGraphicsBeginImageContext(size)  
    let context = UIGraphicsGetCurrentContext() 
    CGContextTranslateCTM(context, 0, size.height) 
    CGContextScaleCTM(context, 1.0, -1.0) 
    let rect = CGRectMake(0, 0, size.width, size.height) 

    // Combine the images 
    for image in images { 
    CGContextDrawImage(context, rect, image.CGImage) 
    } 
    let combinedImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return combinedImage 
}