“回发”的一点总结

 

说来惭愧接触.net一载有余,在和Clingingboy学习控件开发的时候,期间就提到了控件的“回发事件”和“数据回发事件”,当时就晕了头(由于本人愚笨),后来google了一些资料,才发现“原来就是这样的”,希望这”半纸荒唐言“,能对那些还没有亦或即将明白的朋友尽点微薄之力!
    
    在这里,回发事件,我给她起个名字,叫“动作回发事件”,一般就是OnClick回发事件!

   数据回发,当postback后,页面processPostData事件中,调用控件的LoadPostData方法,此方法检查新提交的数据,判断是否与原来的值相同,如果不相等,则更新值,然后控件自动调用RaisePostDataChangedEvent方法!一句话,数据回发就是用来更新值的(在此方法中,可以激活下面的“回发数据事件”)

    数据回发事件,可以这样理解,当触发“动作回发事件”后,控件的值Text如果与原来的Text不相同!由于新值与旧值不同而引发的事件!就叫数据回发事件

一,先看看“动作回发事件”的代码!

publicclassCustomePostBackEventButton:Control,IPostBackEventHandler
    
{
        //
声明Click事件委托
        publiceventEventHandlerClick;
        
//
定义OnClick事件处理程序
        
protectedvirtualvoidOnClick(EventArgse)
        
{
            
if(Click !=null)
            
{
                
Click(this, e);
            
}
        
}
        
//
实现RaisePostBackEvent方法,处理回发事件
        
//
这里就是系统激活“动作回发事件”的入口
        
publicvoidRaisePostBackEvent(stringeventArgument)
        
{
            
OnClick(newEventArgs());
        
}
        
protectedoverridevoidRender(HtmlTextWriteroutput)
        
{
            
output.Write("<input type=submit name="+this.UniqueID +" Value='确定' />"
);
        
}
    
}

代码很简单,继承了处理“动作回发事件”的IPostBackEventHandler接口,并实现了激活“动作回发事件”的入口方法RaisePostBackEvent在这里,因为Click事件是由RaisePostBackEvent方法激活,所以Click就是一个“动作回发事件”!

二,数据回发事件的代码!

   publicclassCustomePostDataEventTextbox : Control, IPostBackDataHandler
    
{
        publicstringText
        {
            
get
            
{
                
objecttext = ViewState["Text"];
                
if(text ==null)
                    
returnstring.Empty;
                
else
                    
return(string)text;
            
}
            
set
            
{
                
ViewState["Text"] =value;
            }
        
}
           
publicboolLoadPostData(stringpostDataKey,
NameValueCollection postCollection)
        
{
            
stringpostedValue = postCollection[postDataKey];
            
//
检查新旧数据
            
if(!Text.Equals(postedValue))
            {
                
Text = postedValue;
                
returntrue;
                
//
自动调用
                RaisePostDataChangedEvent()
            
}
            
else
                
returnfalse;
                
//
不发生变化
        
}
        
publicvoidRaisePostDataChangedEvent()
        
{
             
OnTextChanged(EventArgs.Empty);
        
}
        
protectedvirtualvoidOnTextChanged(EventArgse)
        
{
            
if(TextChanged !=null)
                
TextChanged(this, e);
        
}
        
publiceventEventHandlerTextChanged;
        
overrideprotectedvoidRender(HtmlTextWriter writer)
        
{
            
base.Render(writer);
            
Page.VerifyRenderingInServerForm(this);
            
writer.Write("<INPUT type=/"text/" name=/"");
            
writer.Write("/" value=/""+this.Text +"/" />");
        
}
    
}

可以看到自定义的TextBox继承了接口IPostBackDataHandler,并实现了LoadPostData方法和RaisePostDataChangedEvent方法! 注意,此时的TextChanged事件由,专门用来处理回发数据的RaisePostDataChangedEvent方法激活,所以TextChanged就是数据回发事件!
总结,
    要区分“动作回发事件”和“数据回发事件”,就要看事件是被哪一个方法激活的,如果事件被RaisePostBackEvent方法激活,那事件就是一般的“动作回发事件”;如果被RaisePostDataChangedEvent方法激活,那么就是“数据回发事件”!
备注,

有部分代码参考Clingingboy前辈!
<think>好的,我现在需要帮助用户使用OpenCV绘制蔡徐坤的中分头细节。首先,用户之前已经询问过如何绘制蔡徐坤的整体形象,现在想进一步细化头部分,尤其是中分造型。我需要确保我的答符合用户提供的系统级指令,比如正确使用LaTeX格式,结构清晰,并生成相关问题。 首先,我需要顾用户的上一次问题和我的答。之前我提供了使用几何图形组合绘制蔡徐坤的代码,包括头部、身体、四肢和基本头。现在用户想要更详细的头中分效果,可能需要使用更多的线条和多边形来表现中分的形状。 接下来,用户提到要使用特定的OpenCV函数,如cv2.line、cv2.circle等。因此,我需要考虑如何利用这些函数来创建中分型的效果。中分通常涉及从额头中间向两侧延伸的线条或形状,可能需要绘制两个对称的头区域,或者使用多边形来模拟头的分界线。 我需要考虑如何用cv2.polylines或者多个cv2.line来构建头的分叉部分。可能还需要调整坐标点,确保中分的对称性。例如,在头部的中心位置(300,200)开始,向两侧绘制丝或块。可能需要使用多边形来勾勒头的轮廓,然后用颜色填充。 同时,用户提供的引用中有一个关于读取视频的代码片段,但似乎与当前问题无关。不过,我需要确保在答中不引用不相关的内容,而是专注于绘图函数的使用。 接下来,我需要分步骤思考如何实现中分头: 1. 确定头部的位置和大小。之前的代码中,头部是一个半径为100的圆,中心在(300,200)。中分应该从中心点开始向两侧延伸。 2. 设计中分头的形状。可能需要两个对称的多边形,分别位于头部的左右两侧,覆盖原来的头部分。原来的头是一个多边形,现在需要将其分成两部分,中间留出分界线。 3. 使用cv2.polylines或cv2.fillPoly来绘制左右两侧的头区域,并用黑色填充。同时,在分界处添加线条或小线段来模拟丝,增加细节。 4. 调整坐标点,确保对称性和自然的外观。可能需要数学计算来确定各点的位置,例如使用圆的参数方程或对称点。 5. 可能需要在分界线处添加一些细线,使中分效果更明显。例如,从中心点向左右两侧绘制短线条,模拟头的分缝。 现在,我需要验证这些思路是否可行。例如,原来的头多边形是[[200,150], [250,50], [350,50], [400,150]]。要改为中分,可能需要将这个多边形分成左右两部分,中间添加分界线。或者,重新设计两个对称的多边形,中间留出空隙。 例如,左侧头的多边形可能从头部中心(300,200)向左侧延伸,而右侧同理。或者,在原有头的基础上,从中间分开,调整顶点坐标,形成两个独立的多边形,中间用线条分隔。 另外,可能需要使用cv2.line在分界处画一些细线,模拟头分开的效果。例如,从(300,150)到(300,200)画一条垂直线,或者一些斜线,表示丝的分向。 颜色方面,原来的头是黑色,所以填充颜色保持(0,0,0),分界线可以用同样的颜色或者更深的阴影,但考虑到是线条,可能直接用黑色即可。 在实现时,需要注意绘制顺序,先画头部,再画头,确保头覆盖在头部上方。或者,根据图层顺序调整代码,避免头被头部覆盖。 最后,测试坐标点的位置,可能需要多次调整才能达到理想效果。可以建议用户运行代码后,根据显示效果微调坐标参数。 总结步骤: - 修改原有头多边形,分成左右两部分,中间留出分界线。 - 使用cv2.polylines或cv2.fillPoly绘制左右头区域。 - 在分界线处添加cv2.line绘制丝细节。 - 调整坐标点确保对称性。 现在,将这些步骤转化为具体的代码示例,并解释每个部分的作用,确保用户能够理解如何实现中分效果。同时,需要符合用户的要求,使用指定的OpenCV函数,并保持答结构清晰,分点说明。</think>以下是使用OpenCV绘制蔡徐坤中分头细节的具体实现方法,通过几何图形组合和坐标计算实现分界线效果: --- ### 一、中分头绘制步骤 #### 1. **拆分头为左右对称区域** 将原有头多边形拆分为左右两部分,通过修改顶点坐标实现中分效果: ```python # 左侧头多边形(从中间向左延伸) left_hair = np.array([[300,150], [250,50], [200,50], [200,150]], np.int32) # 右侧头多边形(从中间向右延伸) right_hair = np.array([[300,150], [350,50], [400,50], [400,150]], np.int32) cv2.fillPoly(img, [left_hair], color=(0,0,0)) # 填充左侧 cv2.fillPoly(img, [right_hair], color=(0,0,0)) # 填充右侧 ``` #### 2. **添加分界线细节** 在头中间绘制细线模拟丝分向效果: ```python # 中分基线(垂直线) cv2.line(img, (300,100), (300,200), (0,0,0), 2) # 丝细节(斜线) for y in range(120, 200, 15): cv2.line(img, (300,y), (290,y-10), (0,0,0), 1) # 向左 cv2.line(img, (300,y), (310,y-10), (0,0,0), 1) # 向右 ``` --- ### 二、完整代码整合 ```python import cv2 import numpy as np # 创建白色背景 img = np.zeros((800, 600, 3), dtype=np.uint8) + 255 # 头部(圆心(300,200)) cv2.circle(img, (300, 200), 100, (255, 204, 153), -1) # 中分头(左右对称多边形) left_hair = np.array([[300,150], [250,50], [200,50], [200,150]], np.int32) right_hair = np.array([[300,150], [350,50], [400,50], [400,150]], np.int32) cv2.fillPoly(img, [left_hair], (0,0,0)) cv2.fillPoly(img, [right_hair], (0,0,0)) # 分界线细节 cv2.line(img, (300,100), (300,200), (0,0,0), 2) # 垂直线 for y in range(120, 200, 15): cv2.line(img, (300,y), (290,y-10), (0,0,0), 1) cv2.line(img, (300,y), (310,y-10), (0,0,0), 1) # 身体与面部特征(原代码部分保持不变) # ... [原有身体、手臂、面部等绘制代码] cv2.imshow("KUN", img) cv2.waitKey(0) cv2.destroyAllWindows() ``` --- ### 三、关键数学原理 1. **对称坐标计算** - 头部圆心为$(300,200)$,左右头顶点基于$x=300$对称分布 - 左侧顶点$x$坐标计算:$300 - \Delta x$,右侧为$300 + \Delta x$(例如$\Delta x=50$时,左右顶点分别为250和350) 2. **丝角度控制** 丝斜线斜率通过坐标差值实现: - 向左丝:终点坐标为$(x-\Delta x, y-\Delta y)$,例如$\Delta x=10, \Delta y=10$ - 向右丝:终点坐标为$(x+\Delta x, y-\Delta y)$[^1] --- ### 四、效果优化建议 1. **动态调整参数** ```python delta_x = 10 # 控制丝横向偏移量 delta_y = 8 # 控制丝纵向密度 for y in range(120, 200, delta_y): cv2.line(img, (300,y), (300-delta_x, y-delta_y), (0,0,0), 1) cv2.line(img, (300,y), (300+delta_x, y-delta_y), (0,0,0), 1) ``` 2. **抗锯齿效果** 使用`cv2.line`的`lineType=cv2.LINE_AA`参数: ```python cv2.line(img, (300,100), (300,200), (0,0,0), 2, lineType=cv2.LINE_AA) ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值