美文网首页
颜色混合

颜色混合

作者: Wi1ls努力努力再努力 | 来源:发表于2019-05-08 11:21 被阅读0次

设计给了一个需求,需要在图片的点击态下增加 10%的黑色遮罩。并且只在有 alpha 通道的像素增加。于是需要进行颜色的混合。iOS 的同学已经做完了,于是要了算法

- (UIColor *)bmbw_addColor:(UIColor *)addColor {
  NSArray *baseColorArr = [self bmbw_getRGBA];
  NSArray *addColorArr = [addColor bmbw_getRGBA];

  CGFloat alpha1 = [baseColorArr[3] doubleValue];
  CGFloat alpha2 = [addColorArr[3] doubleValue];
  CGFloat alpha = alpha1 + alpha2 - alpha1 * alpha2;

  CGFloat red1 = [baseColorArr[0] doubleValue];
  CGFloat red2 = [addColorArr[0] doubleValue];
  CGFloat red = (red1 * alpha1 * (1.0 - alpha2) + red2 * alpha2) / alpha;

  CGFloat green1 = [baseColorArr[1] doubleValue];
  CGFloat green2 = [addColorArr[1] doubleValue];
  CGFloat green = (green1 * alpha1 * (1.0 - alpha2) + green2 * alpha2) / alpha;

  CGFloat blue1 = [baseColorArr[2] doubleValue];
  CGFloat blue2 = [addColorArr[2] doubleValue];
  CGFloat blue = (blue1 * alpha1 * (1.0 - alpha2) + blue2 * alpha2) / alpha;

  return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

- (NSArray *)bmbw_getRGBA {
  CGFloat red = 0.0;
  CGFloat green = 0.0;
  CGFloat blue = 0.0;
  CGFloat alpha = 0.0;
  [self getRed:&red green:&green blue:&blue alpha:&alpha];
  return @[@(red), @(green), @(blue), @(alpha)];
}

发现 iOS 的算法对于通道的取值是从 0-1 的,而 Android 是0x00 到0xff,于是要修改一下算法

private Bitmap mixBitmap(Bitmap bitmap) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    // 保存所有的像素的数组,图片宽×高
    int[] pixels = new int[width * height];
    int[] newPixels = new int[width * height];

    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

    int addAlpha = 0x1A;
    int addRed = 0x00;
    int addGreen = 0x00;
    int addBlue = 0x00;


    for (int i = 0; i < pixels.length; i++) {
      int clr = pixels[i];
      int alpha = (clr & 0xff000000) >>> 24;
      if (alpha == 0x00) {
        pixels[i] = 0x00ffffff;
        continue;
      }
      int red = (clr & 0x00ff0000) >>> 16;
      int green = (clr & 0x0000ff00) >>> 8;
      int blue = clr & 0x000000ff;
      //
      int mixAlpha = alpha + addAlpha - alpha * addAlpha / 0xff;
      int mixRed = mixColor(red, alpha, addRed, addAlpha, mixAlpha);
      int mixGreen = mixColor(green, alpha, addGreen, addAlpha, mixAlpha);
      int mixBlue = mixColor(blue, alpha, addBlue, addAlpha, mixAlpha);
      newPixels[i] = Color.argb(mixAlpha, mixRed, mixGreen, mixBlue);
    }
    return Bitmap.createBitmap(newPixels, width, height, Bitmap.Config.ARGB_8888);
  }

  private int mixColor(int or, int oa, int ar, int aa, int ma) {
    return ((or * oa * (0xff - aa) + ar * aa * 0xff) / ma) /0xff;
  }

算法中采取>>>而不是>>,是因为当 在进行移位的时候需要用0 补齐,不然 aplha 是0xff 的时候,通过>>会得到-1;
有些地方用/0xff 而不是>>>8,是为了进位。如果用>>>8实际的时候发现有时候 mixAplha 是 256,而/0xff 则是255;

相关文章

  • OpenGL颜色混合原理

    这就是颜色混合 一。什么情况下会用到颜色混合:1.在固定着色器或者可编程着色器中,开启颜色混合(glEnable(...

  • OpenGL --混合、多重采样

    颜色混合 在OpenGL中使用glEnable(GL_BlEND)来开启颜色混合。目标颜色:已经存储在颜色缓存区的...

  • 十二 浅析OpenGL的颜色混合

    1 颜色混合效果 2 什么情况下使用 在固定着色器或者可编程着色器中,开启颜色混合(glEnable(GL_Bl...

  • OpenGL(4)颜色混合

    为什么要颜色混合?当2个重叠的图层,上面图层是半透明的话,那我们看到的颜色就是上面图层和下面图层的颜色混合的结果。...

  • 颜色混合

    假定一个场景,在OpenGL中,我们需要在一张图层中添加一个透明度为30%的图层,这种情况我们应该怎么做呢? 如上...

  • 颜色混合

    设计给了一个需求,需要在图片的点击态下增加 10%的黑色遮罩。并且只在有 alpha 通道的像素增加。于是需要进行...

  • 色彩混合

    把不同的颜色混合起来,会形成另外的颜色,这就是所谓的混色。一般使用三种颜色进行混合。混色法根据颜色混合后会变亮还是...

  • CGBlendMode研究

    BlendMode颜色混合模式枚举值 https://blog.csdn.net/qq_14920635/arti...

  • glBlendFunc颜色混合

    混合是什么呢?混合就是把两种颜色混在一起。具体一点,就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混...

  • 3.5 颜色混合

    我们把OpenGL渲染时会把颜⾊色值存在颜⾊缓存区中,每个片段的深度值也是放在深度缓冲区。当深度 缓冲区被关闭时,...

网友评论

      本文标题:颜色混合

      本文链接:https://www.haomeiwen.com/subject/daqmoqtx.html