在iOS中合并两个PNG UIImage而不丢失透明度
我有两个png格式的图像,都定义了透明度。我需要将这些合并到一个新的png图像中,但不会丢失结果中的任何透明度在iOS中合并两个PNG UIImage而不丢失透明度,ios,objective-c,Ios,Objective C,我有两个png格式的图像,都定义了透明度。我需要将这些合并到一个新的png图像中,但不会丢失结果中的任何透明度 +(UIImage *) combineImage:(UIImage *)firstImage colorImage:(UIImage *)secondImage { UIGraphicsBeginImageContext(firstImage.size); CGContextRef context = UIGraphicsGetCurrentContext();
+(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;
}
需要任何帮助来提高代码的性能
提前感谢首先,那些对
CGContextSaveGState
和CGContextRestoreGState
的调用,一个接一个,中间什么都没有,对您没有任何帮助。有关CGContextSaveGState
和CGContextRestoreGState
所做操作的说明,请参见此其他答案:
现在,我还不是100%清楚你所说的“合并”图像是什么意思。如果您只想在另一个上面绘制一个,并使用标准混合模式混合它们的颜色,那么您只需要将这些混合模式调用更改为passkcblendmodenormal
(或者完全不调用CGContextSetBlendMode
。如果要用第一个图像的alpha值遮罩第二个图像,则应使用正常混合模式绘制第二个图像,然后切换到kcgblendmodedestin
并绘制第一个图像
恐怕我不太清楚你想用中间的图像着色代码来做什么,但是我的直觉是你最终不会需要它。你应该能够通过绘制一个图像,然后设置混合模式,然后绘制另一个图像来获得大多数的合并效果。
此外,你在“绘制白色背景以保留透明像素的颜色”注释下得到的代码可能会在整个图像中绘制白色,但它肯定不会保留透明像素的颜色,它会使这些像素变白!你也应该删除该代码,除非你真的想要“透明”颜色为白色。使用Vinay的问题和Aaron的评论中给出的代码开发了这种混合型,可以覆盖任意数量的图像:
/**
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
}