输入

  来自wiki,虽然是缩略图但也可以看到,因为光比太大,左边的图能看清亮出细节但看天空漆黑,与之相反的最右边的图能看清天空时整个建筑都爆掉了。



  界面

  右边的两个transform是为了对齐。



  输出

  如图,同一张图片能看清楚云彩和建筑最明亮的地方的细节。效果一般,但就这么滴了。



  把源码发上来吧~


  1. // by cuckon  

  2. #pragma warning(disable:4312)  

  3. #include "DDImage/Iop.h"  

  4. #include "DDImage/Row.h"  

  5. #include "DDImage/Tile.h"  

  6. #include "DDImage/Knobs.h"  

  7. #include <vector>  

  8.  

  9. using namespace DD::Image;  

  10. using namespace std;  

  11.  

  12. #define For(i,from,to) for (int i = from;i<to;i++)  

  13. #define ForI(to) For(i,0,to)  

  14.  

  15. static const char* const CLASS = "BracketStacker";  

  16. static const char* const HELP = "Use to composite brackted images. ";  

  17. typedef vector<Row*> RowList;  

  18.  

  19. const char *const kOperationLabel[] = {  

  20.    "HDRI",  

  21.    "Defocus",  

  22.    NULL  

  23. };  

  24.  

  25. enum Operation {  

  26.    kHDRI = 0,  

  27.    kDefocus  

  28. };  

  29.  

  30. float RGB2Lum(float r,float g, float b) {  

  31.    return 0.2125f * r + 0.7154f * g + 0.0721f * b;  

  32. }  

  33.  

  34. float weightCurve(float dark,float light,float input){  

  35.    input = MIN(1.0f,MAX(input,0.0f));  

  36.    return pow(input,light)  *  pow((1-input),dark);  

  37. }  

  38.  

  39. class BracketStacker : public Iop  

  40. {  

  41.    // These are the locations the user interface will store into:  

  42.    int     operation;  

  43.    double  dark_weight, light_weight,pre_gamma;  

  44. public:  

  45.    BracketStacker(Node*);  

  46.    void _validate(bool);  

  47.    void _request(int, int, int, int, ChannelMask, int);  

  48.    void engine(int y, int x, int r, ChannelMask, Row &);  

  49.    virtual void knobs(Knob_Callback);  

  50.    const char* Class() const { return CLASS; }  

  51.    const char* node_help() const { return HELP; }  

  52.    static const Description d;  

  53.  

  54.    int minimum_inputs()const{return 2;}  

  55.    int maximum_inputs()const{return 99999;}  

  56.  

  57. };  

  58.  

  59. BracketStacker::BracketStacker(Node* node) : Iop(node)  

  60. {  

  61.    operation = 0;  

  62.    dark_weight = 1;  

  63.    light_weight = 1;  

  64.    pre_gamma = 1;  

  65. }  

  66.  

  67. void BracketStacker::knobs(Knob_Callback f)  

  68. {  

  69.    Float_knob(f,&dark_weight,IRange(0,100),"dark","dark");  

  70.    Float_knob(f,&light_weight,IRange(0,100),"light","light");  

  71.    Float_knob(f,&pre_gamma,IRange(0,100),"pre_gamma","pre_gamma");  

  72. }  

  73.  

  74. static Iop* Blocky_c(Node* node) { return new BracketStacker(node); }  

  75. const Iop::Description BracketStacker::d(CLASS, "Cuckon/BracketStacker", Blocky_c);  

  76.  

  77.  

  78. void BracketStacker::_validate(bool for_real)  

  79. {  

  80.    // Get the size and other information from the input image:  

  81.    copy_info();  

  82.    Iop::validate(for_real);  

  83. }  

  84.  

  85. void BracketStacker::_request(int x, int y, int r, int t, ChannelMask channels, int count)  

  86. {  

  87.    for(int i = 0;i<inputs();i++){  

  88.        input(i)->request(x, y, r, t, channels, count);  

  89.    }  

  90. }  

  91.  

  92. void BracketStacker::engine(int y, int l, int r, ChannelMask channels, Row& out)  

  93. {  

  94.    if (!channels.contains(Mask_RGB))  

  95.        return;  

  96.    float   *weight = new float[inputs()],  

  97.            *lum = new float[inputs()],  

  98.            current_lum_sum;  

  99.    Row::WritablePtr    ptr_r = out.writable(Chan_Red),  

  100.                        ptr_g = out.writable(Chan_Green),  

  101.                        ptr_b = out.writable(Chan_Blue);  

  102.      

  103.    // prepare all rows for calc  

  104. 点赞(0)