mikespook

懒猫开始新生活——猫眼看世界
本人乃好事之徒,找骂者请自便
PS:如果哪天我不跟坎子找茬了,那我就是死了。^_^
随笔 - 121, 文章 - 0, 评论 - 544, 引用 - 3
数据加载中……

原来一直对FillRectangle理解有误

今天一个朋友问我他在使用FillRectangle向窗体绘制图象的时候总是发生错位,不知道是怎么回事。我拿代码来看了一下,中规中矩的代码:
        private void DrawTitle_Right(Graphics g)
        
{
            Image img 
= Files.GetImage("/Images/Top_Right.gif");
            Brush brush 
= new TextureBrush(img);
            g.FillRectangle(brush, 
this.ClientSize.Width-img.Width, 0, img.Width, img.Height);   
        }

但是为什么会错位呢?我调试了半天,结果和他实验的一样。而使用DrawImage就不会有问题。后来看了半天错位的规律才发现原来:
“FillRectangle是填充一个Graphics,然后显示Rectangle指定的部分。”
如图,假设图片的大小就是Graphics的大小。FillRectangle做的操作就是以马赛克的方式先填充这个Graphics,然后再真实绘制Rectangle指定的矩形(当然实际实现可能不是这样,但是效果是这样的。让我想起来小时候跟我妈在暗房里洗照片,用小窗的方法用5寸的放大纸冲洗1寸相片^&^)。

当FillRectangle指定的Rect正好跟GetImage来的图片吻合时,显示正常。如果不吻合时就会发生错位的情况。这跟自己一直理解的:
“FillRectangle就是用指定的图象填充坐标在(x, y)处,宽width,高height的矩形。”
还是有出入的(这个理解是Delphi带来的后遗症!-_-!)。

----------------------------------------------------------------------------------------
看了朋友们的回复,回头看了看自己写的东西。
的确感觉还是说得不是那么清楚,用代码来证明一切吧:下载代码

posted on 2005-01-31 15:32 mikespook 阅读(1521) 评论(8)  编辑 收藏 所属分类: 编程

评论

#1楼    回复  引用  查看    

还是理解有误吧。
问题的关键在于TextureBrush这个东西里。
它是用Brush来填充的。要理解Brush。
2005-01-31 15:00 | lichdr      

#2楼    回复  引用  查看    

原来如些,看了这个图后就明白了

第一次看这个方法确实很容易让人造成误解
“FillRectangle是填充一个Graphics,然后显示Rectangle指定的部分。”

2005-01-31 15:01 | Lion      

#3楼 [楼主]   回复  引用  查看    

@ lichdr
可能我没有表达清楚~~呵呵~~~其实就是类似小窗~~~~
brush我是理解了,只不过受到Delphi里方法命名的影响,这里理解的有偏差。
恩,写一段代码你看看,应该能理解我的意思。
2005-01-31 15:14 | mikespook      

#4楼    回复  引用  查看    

我写了一篇随笔解释了一下,在我的blog上。
2005-02-02 15:46 | xingd      

#5楼 [楼主]   回复  引用  查看    

我已经看了,不过代码我怎么实验都是没有效果,不知道什么原因。

“为抵色处理和阴影画笔获取或设置此 Graphics 对象的呈现原点。”
这是MSDN上的解释。“抵色处理”是什么?我怎么想都没想明白,是底色么?
2005-02-02 16:56 | mikespook      

#6楼    回复  引用  查看    

我也有理解错误,已经更新了一篇新的blog
2005-02-02 18:21 | xingd      

#7楼    回复  引用  查看    

英文版MSDN的解释是
rendering origin of this Graphics object for dithering and for hatch brushes.
dithering是抖动的意思,可能在一些图像处理中有作用吧。

我对GDI+也有一些了解,有机会多交流吧。
2005-02-02 18:24 | xingd      

#8楼    回复  引用  查看    

哎呀,郁闷啊 ,想做一个winform skin碰到这个问题也害我弄了一天找资料,最后搜到你这里,看了明白了一些,后来又搜索CSDN发现[终于解决问题] :

http://blog.csdn.net/tjvictor/archive/2006/05/28/758331.aspx
下面是我的源代碼,我將一步一步的分析出現這個問題的原因及解決方法。

Image logo = Image.FromFile( " Your Picture Path" );
TextureBrush br = new TextureBrush( logo );
Graphics g = this.CreateGraphics();
g.FillRectangle( br , 22 , 29 , 20 , 20 );

原因就在於g.FillRectangle( br , 22 , 29 , 20 , 20 ); 中的22 ,29 。原來我認為22 ,29 隻是來確定你要顯示的圖片在form中的相對位置( x ,y ),但是用TextureBrush時(22 ,29) ,不僅是確定位置的,而且還決定了圖片的偏移大小 ,你如果把其換成其它的數,那麼圖片的偏移還會變的。把g.FillRectangle( br , 22 , 29 , 20 , 20 ); 改成g.FillRectangle( br , 0 , 0 , 20 , 20 ); ,圖像顯示正常,但是其位置確是(0 , 0),所以這也驗証了我上述的猜想是正確的。

解決方法:

Image logo = Image.FromFile( "D:\\EPON_EMS\\image\\green.png" );
TextureBrush br = new TextureBrush( logo );
br.TranslateTransform( 22 , 29 );
Graphics g = LIU1.CreateGraphics();
g.FillRectangle( br , 22 , 29 , 20 , 20 );

加上一句br.TranslateTransform( 22 , 29 );就OK了,TranslateTransform是把原始圖像的起始位置進行偏移,這樣我們就相當於先將它偏移,然後在FillRectangle中又將它偏移了過來,這樣簡單的達到了我們的目的。

2007-05-21 18:56 | asboy      

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-03-04 11:51 编辑过


相关链接: