Ios 彩色图像忽略alpha通道—;为什么以及如何修复?

Ios 彩色图像忽略alpha通道—;为什么以及如何修复?,ios,opacity,quartz-2d,alphablending,colorize,Ios,Opacity,Quartz 2d,Alphablending,Colorize,下面是我正在尝试做的:左侧的是一个通用的未着色RGBA图像,我在屏幕外创建了它,并缓存了它以提高速度(最初创建速度非常慢,但稍后根据需要使用任何颜色着色速度非常快)。这是一个带有圆形漩涡的正方形图像。在圆内,图像的alpha/不透明度为1。在圆外,其alpha/不透明度为0。我在UIView中显示了它,背景颜色为[UIColor scrollViewTexturedBackgroundColor]右侧的是在设置CGContextSetBlendMode(context,kCGBlendModeC

下面是我正在尝试做的:左侧的是一个通用的未着色RGBA图像,我在屏幕外创建了它,并缓存了它以提高速度(最初创建速度非常慢,但稍后根据需要使用任何颜色着色速度非常快)。这是一个带有圆形漩涡的正方形图像。在圆内,图像的alpha/不透明度为1。在圆外,其alpha/不透明度为0。我在UIView中显示了它,背景颜色为
[UIColor scrollViewTexturedBackgroundColor]
右侧的是在设置
CGContextSetBlendMode(context,kCGBlendModeColor)
后,试图通过在图像顶部填充一个红色实心矩形来给图像上色时发生的情况

这不是我想要的,也不是我期望的。显然,由于某些奇怪的原因,对完全透明的像素(例如,alpha值为0)着色会导致完全填充颜色,而不是像我预期的那样保持透明

我想要的其实是:

现在,在这个特殊的例子中,我可以将剪切区域设置为一个圆,这样圆外的区域就不会被触及——这就是我在这里所做的解决方法

但在我的应用程序中,我还需要能够对我不知道剪裁/轮廓路径的任意形状进行着色。一个例子是通过叠加渐变为白色文本上色。这是怎么做到的?我怀疑一定有某种方法可以有效地做到这一点-通常,没有奇怪的路径/剪辑技巧-使用图像遮罩。。。但是我还没有找到关于这个的教程。显然这是可能的,因为我在其他游戏中见过彩色渐变文本

顺便说一句,我不能做的是从渐变开始,然后剪辑/清除我不需要的部分——因为(如上面的例子所示)我的未着色源图像通常是灰度级的,而不是纯白色的。所以我真的需要从未着色的图像开始,然后对其着色


p、 s.-
kCGBlendModeMultiply
在对部分透明图像进行着色时也有相同的缺陷/缺点/特性。有人知道苹果为什么决定这样做吗?这就好像石英着色代码将RGBA(0,0,0,0)视为RGBA(0,0,0,1),即完全忽略并破坏alpha通道。

可以采用的一种方法是从原始图像构造一个遮罩,然后在使用倍增混合模式集渲染图像之前调用CGContextClipToMask()方法。以下是CoreGraphics代码,它将在将图像绘制为彩色之前设置遮罩

  CGContextRef context = [frameBuffer createBitmapContext];
  CGRect bounds = CGRectMake( 0.0f, 0.0f, width, height );
  CGContextClipToMask(context, bounds, maskImage.CGImage);
  CGContextDrawImage(context, bounds, greyImage.CGImage);
稍微复杂一点的部分是拍摄原始图像并生成一个maskImage。你能做的就是写一个循环,检查每个像素,并写一个黑色或白色像素作为遮罩值。如果要着色的图像中的原始像素是完全透明的,则写入黑色像素,否则写入白色像素。请注意,掩码值将为24BPP图像。下面是一些代码,让您了解正确的想法

  uint32_t *inPixels = (uint32_t*) MEMORY_ADDR_OF_ORIGINAL_IMAGE;
  uint32_t *maskPixels = malloc(numPixels * sizeof(uint32_t));
  uint32_t *maskPixelsPtr = maskPixels;

  for (int rowi = 0; rowi < height; rowi++) {
    for (int coli = 0; coli < width; coli++) {
      uint32_t inPixel = *inPixels++;
      uint32_t inAlpha = (inPixel >> 24) & 0xFF;
      uint32_t cval = 0;
      if (inAlpha != 0) {
        cval = 0xFF;
      }
      uint32_t outPixel = (0xFF << 24) | (cval << 16) | (cval << 8) | cval;
      *maskPixelsPtr++ = outPixel;
    }
  }
uint32\u t*inPixels=(uint32\u t*)原始图像的内存地址;
uint32_t*maskPixels=malloc(numPixels*sizeof(uint32_t));
uint32_t*maskPixelsPtr=maskPixels;
对于(int-rowi=0;rowi>24)和0xFF;
uint32_t cval=0;
如果(inAlpha!=0){
cval=0xFF;
}
uint32_t输出像素=(0xFF