示例#1
0
void NatePixTable::Frame::load_overlay(const PixMap& pix, uint8_t color) {
    for (auto x : range(width())) {
        for (auto y : range(height())) {
            RgbColor over  = pix.get(x, y);
            uint8_t  value = over.red;
            uint8_t  frac  = over.alpha;
            over           = RgbColor::tint(color, value);
            RgbColor under = _pix_map.get(x, y);
            RgbColor composite;
            composite.red   = ((over.red * frac) + (under.red * (255 - frac))) / 255;
            composite.green = ((over.green * frac) + (under.green * (255 - frac))) / 255;
            composite.blue  = ((over.blue * frac) + (under.blue * (255 - frac))) / 255;
            composite.alpha = under.alpha;
            _pix_map.set(x, y, composite);
        }
    }
}
示例#2
0
void PixMap::composite(const PixMap& pix) {
    if (size() != pix.size()) {
        throw Exception("Mismatch in PixMap sizes");
    }
    for (int y = 0; y < size().height; ++y) {
        for (int x = 0; x < size().width; ++x) {
            const RgbColor& over = pix.get(x, y);
            const double oa = over.alpha / 255.0;
            const RgbColor& under = get(x, y);
            const double ua = under.alpha / 255.0;

            // TODO(sfiera): if we're going to do anything like this in the long run, we should
            // require that alpha be pre-multiplied with the color components.  We should probably
            // also use integral arithmetic.
            double red   = (over.red   * oa) + ((under.red   * ua) * (1.0 - oa));
            double green = (over.green * oa) + ((under.green * ua) * (1.0 - oa));
            double blue  = (over.blue  * oa) + ((under.blue  * ua) * (1.0 - oa));
            double alpha = oa + (ua * (1.0 - oa));
            set(x, y, RgbColor(alpha * 255, red / alpha, green / alpha, blue / alpha));
        }
    }
}