Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS中合并两个PNG UIImage而不丢失透明度_Ios_Objective C - Fatal编程技术网

在iOS中合并两个PNG UIImage而不丢失透明度

在iOS中合并两个PNG UIImage而不丢失透明度,ios,objective-c,Ios,Objective C,我有两个png格式的图像,都定义了透明度。我需要将这些合并到一个新的png图像中,但不会丢失结果中的任何透明度 +(UIImage *) combineImage:(UIImage *)firstImage colorImage:(UIImage *)secondImage { UIGraphicsBeginImageContext(firstImage.size); CGContextRef context = UIGraphicsGetCurrentContext();

我有两个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;
}
需要任何帮助来提高代码的性能


提前感谢

首先,那些对
CGContextSaveGState
CGContextRestoreGState
的调用,一个接一个,中间什么都没有,对您没有任何帮助。有关
CGContextSaveGState
CGContextRestoreGState
所做操作的说明,请参见此其他答案:

现在,我还不是100%清楚你所说的“合并”图像是什么意思。如果您只想在另一个上面绘制一个,并使用标准混合模式混合它们的颜色,那么您只需要将这些混合模式调用更改为pass
kcblendmodenormal
(或者完全不调用
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
}