//#include "trop.h" #include "tfxparam.h" #include #include "stdfx.h" #include "hsvutil.h" #include "globalcontrollablefx.h" class HSVKeyFx final : public GlobalControllableFx { FX_PLUGIN_DECLARATION(HSVKeyFx) TRasterFxPort m_input; TDoubleParamP m_h; TDoubleParamP m_s; TDoubleParamP m_v; TDoubleParamP m_hrange; TDoubleParamP m_srange; TDoubleParamP m_vrange; TBoolParamP m_gender; public: HSVKeyFx() : m_h(0.0) , m_s(0.0) , m_v(0.0) , m_hrange(0.0) , m_srange(0.0) , m_vrange(0.0) , m_gender(false) { bindParam(this, "h", m_h); bindParam(this, "s", m_s); bindParam(this, "v", m_v); bindParam(this, "h_range", m_hrange); bindParam(this, "s_range", m_srange); bindParam(this, "v_range", m_vrange); bindParam(this, "invert", m_gender); m_h->setValueRange(0.0, 360.0); m_s->setValueRange(0.0, 1.0); m_v->setValueRange(0.0, 1.0); m_hrange->setValueRange(0.0, 360.0); m_srange->setValueRange(0.0, 1.0); m_vrange->setValueRange(0.0, 1.0); addInputPort("Source", m_input); } ~HSVKeyFx(){}; bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) override { if (m_input.isConnected()) { m_input->doGetBBox(frame, bBox, info); return true; } return false; }; void doCompute(TTile &tile, double frame, const TRenderSettings &) override; bool canHandle(const TRenderSettings &info, double frame) override { return true; } }; //------------------------------------------------------------------------------ template void doHSVKey(const TRasterPT &ras, double lowH, double highH, double lowS, double highS, double lowV, double highV, bool gender) { double aux = (double)PIXEL::maxChannelValue; int j; ras->lock(); for (j = 0; j < ras->getLy(); j++) { PIXEL *pix = ras->pixels(j); PIXEL *endPix = pix + ras->getLx(); while (pix < endPix) { double h, s, v; OLDRGB2HSV(pix->r / aux, pix->g / aux, pix->b / aux, &h, &s, &v); bool condition = h >= lowH && h <= highH && s >= lowS && s <= highS && v >= lowV && v <= highV; if (condition != gender) *pix = PIXEL::Transparent; pix++; } } ras->unlock(); } //------------------------------------------------------------------------------ void HSVKeyFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { if (!m_input.isConnected()) return; m_input->compute(tile, frame, ri); double h_ref = m_h->getValue(frame); double s_ref = m_s->getValue(frame); double v_ref = m_v->getValue(frame); double h_range = m_hrange->getValue(frame); double s_range = m_srange->getValue(frame); double v_range = m_vrange->getValue(frame); bool gender = (int)m_gender->getValue(); double lowH = std::max(0.0, h_ref - h_range); double highH = std::min(360.0, h_ref + h_range); double lowS = std::max(0.0, s_ref - s_range); double highS = std::min(1.0, s_ref + s_range); double lowV = std::max(0.0, v_ref - v_range); double highV = std::min(1.0, v_ref + v_range); TRaster32P raster32 = tile.getRaster(); if (raster32) doHSVKey(raster32, lowH, highH, lowS, highS, lowV, highV, gender); else { TRaster64P raster64 = tile.getRaster(); if (raster64) doHSVKey(raster64, lowH, highH, lowS, highS, lowV, highV, gender); else throw TException("HSVKey: unsupported Pixel Type"); } } //------------------------------------------------------------------ FX_PLUGIN_IDENTIFIER(HSVKeyFx, "hsvKeyFx")