PVideoFrame __stdcall ImasMultiColorKeying::GetFrame(int n, IScriptEnvironment *env) { PVideoFrame frame_r1 = clip_r1->GetFrame(n, env); PVideoFrame frame_r2 = clip_r2->GetFrame(n, env); PVideoFrame frame_r3 = clip_r3->GetFrame(n, env); PVideoFrame frame_g1 = clip_g1->GetFrame(n, env); PVideoFrame frame_g2 = clip_g2->GetFrame(n, env); PVideoFrame frame_g3 = clip_g3->GetFrame(n, env); PVideoFrame frame_result = env->NewVideoFrame(vi); const AS_RGBA *ptr_r1 = (const AS_RGBA *)frame_r1->GetReadPtr(); const AS_RGBA *ptr_r2 = (const AS_RGBA *)frame_r2->GetReadPtr(); const AS_RGBA *ptr_r3 = (const AS_RGBA *)frame_r3->GetReadPtr(); const AS_RGBA *ptr_g1 = (const AS_RGBA *)frame_g1->GetReadPtr(); const AS_RGBA *ptr_g2 = (const AS_RGBA *)frame_g2->GetReadPtr(); const AS_RGBA *ptr_g3 = (const AS_RGBA *)frame_g3->GetReadPtr(); AS_RGBA *ptr_result = (AS_RGBA *)frame_result->GetWritePtr(); AS_RGBA *ptr_result_end = (AS_RGBA *)((BYTE *)ptr_result + frame_result->GetHeight() * frame_result->GetPitch()); AS_RGBA rgba; for (AS_RGBA *p = ptr_result; p < ptr_result_end; p++) { double ar1g1 = 1.0 - ((int)ptr_g1->g - (int)ptr_r1->g) / 255.0; double ar2g1 = 1.0 - ((int)ptr_g1->g - (int)ptr_r2->g) / 255.0; double ar3g1 = 1.0 - ((int)ptr_g1->g - (int)ptr_r3->g) / 255.0; double ar1g2 = 1.0 - ((int)ptr_g2->g - (int)ptr_r1->g) / 255.0; double ar2g2 = 1.0 - ((int)ptr_g2->g - (int)ptr_r2->g) / 255.0; double ar3g2 = 1.0 - ((int)ptr_g2->g - (int)ptr_r3->g) / 255.0; double ar1g3 = 1.0 - ((int)ptr_g3->g - (int)ptr_r1->g) / 255.0; double ar2g3 = 1.0 - ((int)ptr_g3->g - (int)ptr_r2->g) / 255.0; double ar3g3 = 1.0 - ((int)ptr_g3->g - (int)ptr_r3->g) / 255.0; double a = max(max(max(max(max(max(max(max(ar1g1, ar1g2), ar1g3), ar2g1), ar2g2), ar2g3), ar3g1), ar3g2), ar3g3); // 馬鹿 a = clipval(a, 0.0, 1.0); if (a == 0.0) { rgba.b = 0; rgba.g = 0; rgba.r = 0; rgba.a = 0; } else { rgba.b = (BYTE)clipval((ptr_g1->b - 8 * (1.0 - a)) / a, 0.0, 255.9); rgba.g = (BYTE)clipval((ptr_g1->g - 255 * (1.0 - a)) / a, 0.0, 255.9); rgba.r = (BYTE)clipval((ptr_g1->r - 19 * (1.0 - a)) / a, 0.0, 255.9); rgba.a = (BYTE)(a*255); } *p = rgba; ptr_r1++; ptr_r2++; ptr_r3++; ptr_g1++; ptr_g2++; ptr_g3++; } return frame_result; }
void applyImageTransparancy(QImage& img, const Numpy2DObj& data) { const int xw = min(data.dims[1], img.width()); const int yw = min(data.dims[0], img.height()); for(int y=0; y<yw; ++y) { // direction of images is different for qt and numpy image QRgb* scanline = reinterpret_cast<QRgb*>(img.scanLine(yw-y-1)); for(int x=0; x<xw; ++x) { const double val = clipval(data(x, y), 0., 1.); const QRgb col = *(scanline+x); // update pixel alpha component QRgb newcol = qRgba( qRed(col), qGreen(col), qBlue(col), int(qAlpha(col)*val) ); *(scanline+x) = newcol; } } }
QImage numpyToQImage(const Numpy2DObj& imgdata, const Numpy2DIntObj &colors, bool forcetrans) { // make format use alpha transparency if required const int numcolors = colors.dims[0]; if ( colors.dims[1] != 4 ) throw "4 columns required in colors array"; if ( numcolors < 1 ) throw "at least 1 color required"; const int numbands = numcolors-1; const int xw = imgdata.dims[1]; const int yw = imgdata.dims[0]; // if the first value in the color is -1 then switch to jumping mode const bool jumps = colors(0,0) == -1; QImage::Format format = QImage::Format_RGB32; if( forcetrans ) format = QImage::Format_ARGB32; else { for(int i = 0; i < numcolors; ++i) { if( colors(i, 3) != 255 ) format = QImage::Format_ARGB32; } } // make image QImage img(xw, yw, format); // iterate over input pixels for(int y=0; y<yw; ++y) { // direction of images is different for qt and numpy image QRgb* scanline = reinterpret_cast<QRgb*>(img.scanLine(yw-y-1)); for(int x=0; x<xw; ++x) { double val = imgdata(x, y); // output color int b, g, r, a; if( ! isFinite(val) ) { // transparent b = g = r = a = 0; } else { val = clipval(val, 0., 1.); if( jumps ) { // jumps between colours in discrete mode // (ignores 1st color, which signals this mode) const int band = clipval(int(val*(numcolors-1))+1, 1, numcolors-1); b = colors(0, band); g = colors(1, band); r = colors(2, band); a = colors(3, band); } else { // do linear interpolation between bands // make sure between 0 and 1 const int band = clipval(int(val*numbands), 0, numbands-1); const double delta = val*numbands - band; // ensure we don't read beyond where we should const int band2 = min(band + 1, numbands); const double delta1 = 1.-delta; b = int(delta1*colors(0, band) + delta *colors(0, band2)); g = int(delta1*colors(1, band) + delta *colors(1, band2)); r = int(delta1*colors(2, band) + delta *colors(2, band2)); a = int(delta1*colors(3, band) + delta *colors(3, band2)); } } *(scanline+x) = qRgba(r, g, b, a); } } return img; }