virtual ImageEx render( const ImageEx& img ) const override{ switch( method ){ case 1: return img.copyApplyAll( true, &Plane::blur_box, width, height ); break; case 2: return img.copyApplyAll( true, &Plane::blur_gaussian, width, height ); break; default: return img; } }
//////////////////////////////////////////////////////////////////////////////// // // FUNCTION: ImageEx::_ThreadAnimationProc // // DESCRIPTION: Thread to draw animated gifs // // RETURNS: // // NOTES: // // MODIFICATIONS: // // Name Date Version Comments // N T ALMOND 29012002 1.0 Origin // //////////////////////////////////////////////////////////////////////////////// UINT WINAPI ImageEx::_ThreadAnimationProc(LPVOID pParam) { ASSERT(pParam); ImageEx *pImage = reinterpret_cast<ImageEx *> (pParam); pImage->ThreadAnimation(); return 0; }
int AnimationSaver::addImage( const ImageEx& img ){ //Create thumbnail for first frame if( current_id == 1 ){ ImageEx temp( img ); //TODO: fix const on to_qimage! QImage raw = temp.to_qimage( ImageEx::SYSTEM_REC709, ImageEx::SETTING_DITHER | ImageEx::SETTING_GAMMA ); raw.scaled( 256, 256, Qt::KeepAspectRatio ) .save( folder + "/Thumbnails/thumbnail.jpg", nullptr, 95 ); } QString filename = "data/" + numberZeroFill( current_id++, 4 ) + ".dump"; //TODO: allow file format to be changed? img.saveDump( (folder + "/" + filename).toLocal8Bit().constData() ); images.push_back( {filename, QSize( img.get_width(), img.get_height() )} ); return images.size() - 1; }
double ImageEx::diff( const ImageEx& img, int x, int y ) const{ //Check if valid if( !is_valid() || !img.is_valid() ) return DOUBLE_MAX; return planes[0].p.diff( img[0], x, y ); }
ImageCache get( ImageCache img ){ if( !renderNeeded() ) return img; if( img.second || !cache.is_valid() ){ cache = render( img.first ); base = &img.first; } return ImageCache( cache, true ); }
ImageEx Overmix::deVlcImage( const ImageEx& img ){ Timer t( "deVlcImage" ); if( !img.getColorSpace().isRgb() ) return {}; ImageEx out( img.getColorSpace().changed( Transform::YCbCr_709 ) ); //TODO: transfer? for( int i=0; i<3; i++ ) out.addPlane( Plane( img[i] ) ); for( unsigned iy=0; iy<img.get_height(); iy++ ){ ColorRow row( out, iy ); for( unsigned ix=0; ix<img.get_width(); ix++ ) row.set( ix, row[ix].rgbToYcbcr( 0.299, 0.587, 0.114, false, true ) ); } //Downscale chroma for( int c=1; c<3; c++ ){ Plane downscaled( out[c].getSize() / 2 ); for( unsigned iy=0; iy<downscaled.get_height(); iy++ ){ auto row_in1 = out[c].scan_line( iy*2 ); auto row_in2 = out[c].scan_line( iy*2+1 ); auto row_out = downscaled. scan_line( iy ); for( unsigned ix=0; ix<downscaled.get_width(); ix++ ) row_out[ix] = ( row_in1[ix*2+0] + row_in1[ix*2+1] + row_in2[ix*2+0] + row_in2[ix*2+1] ) / 4; } out[c] = downscaled; } //TODO: check consistency? return out; }
MergeResult ImageEx::best_round( const ImageEx& img, int level, double range_x, double range_y, DiffCache *cache ) const{ //Bail if invalid settings if( level < 1 || ( range_x < 0.0 || range_x > 1.0 ) || ( range_y < 0.0 || range_y > 1.0 ) || !is_valid() || !img.is_valid() ) return MergeResult({0,0}, DOUBLE_MAX); //Make sure cache exists DiffCache temp; if( !cache ) cache = &temp; return planes[0].p.best_round_sub( img[0], alpha_plane(), img.alpha_plane(), level , ((int)1 - (int)img.get_width()) * range_x, ((int)get_width() - 1) * range_x , ((int)1 - (int)img.get_height()) * range_y, ((int)get_height() - 1) * range_y , cache, true ); }
void ImageEx::copyFrom( const ImageEx& source, Point<unsigned> source_pos, Size<unsigned> source_size, Point<unsigned> to_pos ){ //Validate if( size() != source.size() ) throw std::runtime_error( "ImageEx::copyFrom() - not the same number of image planes" ); for( unsigned c=0; c<size(); c++ ) if( planeScale(c) != source.planeScale(c) ) throw std::runtime_error( "ImageEx::copyFrom() - subplanes have different scales" ); auto resize = [&](const Plane& p){ Plane out( getSize() ); out.fill( color::BLACK ); out.copy( p, source_pos, source_size, to_pos ); return out; }; //TODO: Handle sub-sampling PorterDuff duffer( resize(source.alpha), alpha ); for( unsigned c=0; c<size(); c++ ) planes[c].p = duffer.over( resize( source.planes[c].p ), planes[c].p ); alpha = duffer.overAlpha(); }
ImageEx ImageEx::fromFile( QString path ){ ImageEx temp; if( !temp.read_file( path ) ) return {}; return temp; }
void ImageEx::combine_line( ImageEx& img, bool top ){ for( unsigned i=0; i<max(size(), img.size()); ++i ) planes[i].p.combine_line( img[i], top ); if( alpha && img.alpha_plane() ) alpha.combine_line( img.alpha_plane(), top ); }
ImageEx ProcessDeconvolve::process( const ImageEx& input ) const{ return input.deconvolve_rl( deviation->getValue(), iterations->value() ); }
virtual ImageEx render( const ImageEx& img ) const override{ return img.copyApply( &Plane::deconvolve_rl, deviation, iterations ); }
virtual ImageEx render( const ImageEx& img ) const override{ return img.copyApply( &Plane::level, limit_min, limit_max, out_min, out_max, gamma ); }
const Plane& alpha( const std::vector<Plane>& masks ) const{ return ( mask_id >= 0 ) ? masks[mask_id] : (mask ? mask : img.alpha_plane()); }