1

2 つの 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何をして何をするかについては、この他の回答を参照してCGContextRestoreGStateください: CGContextSaveGState vs UIGraphicsPushContext

さて、画像を「マージ」することの意味が 100% 明確ではありません。一方を他方の上に描画し、標準のブレンド モードを使用してそれらの色をブレンドする場合は、それらのブレンド モード呼び出しを渡すように変更するだけですkCGBlendModeNormal(または呼び出しをCGContextSetBlendMode完全に除外する必要があります。マスクしたい場合は、最初の画像のアルファ値によって 2 番目の画像を描画する場合は、通常のブレンド モードで 2 番目の画像を描画してからkCGBlendModeDestinationIn、最初の画像に切り替えて描画する必要があります。

残念ながら、途中の画像着色コードで何をしようとしているのかよくわかりませんが、私の本能は、あなたがそれを必要としないということです. 1 つの画像を描画し、ブレンド モードを設定してから、もう 1 つの画像を描画するだけで、ほとんどの結合効果を得ることができるはずです。

また、「透明ピクセルの色を保持するために白い背景を描画する」というコメントの下にあるコードは、画像全体に白を描画する可能性がありますが、透明ピクセルの色を保持するのではなく、それらのピクセルを白にします! 「透明な」色を本当に白にしたい場合を除き、そのコードも削除する必要があります。

于 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 に答える