1

我有两个 png 格式的图像,并且都定义了透明度。我需要将它们合并到一个新的 png 图像中,但不会丢失结果中的任何透明度。

+(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;
}

需要任何帮助来提高我的代码的性能。

提前致谢

4

2 回答 2

3

首先,那些对CGContextSaveGStateand的调用CGContextRestoreGState,一个接一个,中间什么都没有,对你没有任何作用。CGContextSaveGState有关做什么和做什么的解释,请参见其他答案CGContextRestoreGStateCGContextSaveGState vs UIGraphicsPushContext

现在,我还不是 100% 清楚你所说的“合并”图像是什么意思。如果您只想在另一个之上绘制一个,并使用标准混合模式混合它们的颜色,那么您只需将这些混合模式调用更改为通过kCGBlendModeNormal(或完全忽略调用CGContextSetBlendMode。如果您想掩盖通过第一张图像的 alpha 值绘制第二张图像,然后您应该使用正常混合模式绘制第二张图像,然后切换到kCGBlendModeDestinationIn并绘制第一张图像。

恐怕我不太确定你想用中间的图像着色代码做什么,但我的直觉是你最终不会需要它。您应该能够通过仅绘制一张图像,然后设置混合模式,然后绘制另一张图像来获得大多数合并效果。

此外,您在注释“绘制白色背景以保留透明像素的颜色”下获得的代码可能会在整个图像中绘制白色,但它肯定不会保留透明像素的颜色,它会使这些像素变成白色!您也应该删除该代码,除非您真的希望您的“透明”颜色为白色。

于 2013-05-29T17:53:19.763 回答
0

使用 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
}
于 2016-05-13T03:37:58.003 回答