PaintBox的显示图片问题

雄牛 2014-02-10 11:42:01
PaintBox1放在一个ScrollBox1里,
为什么PaintBox在显示一个图片的时候,如果太大了,当移动滚动条时,超出的部份就显示不了?
而且也操作不了超出部份的像素点?

有没什么办法?我的加载图片代码如下:

procedure TMainForm.open1Click(Sender: TObject);
var
bm: TBitmap;
begin
if OpenPictureDialog1.Execute then
begin
bm := TBitmap.Create;
bm.LoadFromFile(OpenPictureDialog1.FileName);
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
PaintBox1.Canvas.CopyRect(Rect(PaintBox1.Left, PaintBox1.Top,
PaintBox1.Width, PaintBox1.Height), bm.Canvas,
Rect(0, 0, bm.Width, bm.Height));

end;
end;
...全文
579 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
mggsaca 2014-02-26
  • 打赏
  • 举报
回复
如果仅仅是显示图片,就使用 TImage 就可以了,比较省事, 如果还有其它的计算,或要同时绘制其它图形,就使用 TPaintBox。 TPaintBox 的执行速度快,节省内存,但编程麻烦,需要把绘图代码写到 OnPaint 事件中,因为在窗口滚动时,无效区会自动清除。 如果是更复杂的绘图,则干脆写个VCL控件,从 WinControl 继承,这样就更灵活了。
sololie 2014-02-17
  • 打赏
  • 举报
回复
另外推荐一个组件 Graphics32,非常不错
sololie 2014-02-17
  • 打赏
  • 举报
回复
俺这样说有点不太准确,不过大致意思就是这样了。反正就是没有显示在PAINTOBOX中的内容就在原图中处理好后再bitblt显拷到PAINTBOX中
星際訪客 2014-02-17
  • 打赏
  • 举报
回复
引用 17 楼 sololie 的回复:
今晚有球赛,足总杯和意甲
呵~ 原來如此...晚安! 先睡覺去了~
sololie 2014-02-17
  • 打赏
  • 举报
回复
今晚有球赛,足总杯和意甲
星際訪客 2014-02-17
  • 打赏
  • 举报
回复
引用 15 楼 sololie 的回复:
另外推荐一个组件 Graphics32,非常不错
哇~ 又當夜貓子啦~ 樓主的問題...我昨天實際模擬過很容易實現呀~ 實在不明白 TImage 有何不能進行大量繪圖的? 只要把 TImage.Canvas 當幕後繪製再複製顯示不行嗎?
sololie 2014-02-16
  • 打赏
  • 举报
回复
原因还是你根本没看懂这个代码的原理 假如有一个原图BMP,width=500,height=300,将pb1的高宽指定为这个BMP的高宽 pb1.width:=500, pb1.height:=300 ScrollBox1.width:=300, ScrollBox1.height:=200 pb1放在上面这个滚动盒里 滚动条移动时,并不是移动pb1的位置,pb1实际上始终没有动过 滚动条移动时,根据这个移动的量来计算要显示的区域,然后从BMP中把要显示的区域拷贝到pb1中 pb1只有在ScrollBox1区域中的部分才有(bitblt上去的)像素,不被显示的其他区域的像素不存在于pb1中 所以你应该对这个原图BMP.canvas 进行操作
雄牛 2014-02-16
  • 打赏
  • 举报
回复
引用 11 楼 start8588 的回复:
以樓主的例子...關鍵是使用 TImage.Canvas 當畫布...而不是使用 TPaintBox.Canvas 當畫布...因為 TImage 裡有一個內存位圖與重繪更新機制......
因为要进行大量的绘图计算,而且images有的功能实现不了,还有办法吗
雄牛 2014-02-13
  • 打赏
  • 举报
回复
算了,我还是限制图片长宽吧.. 谢谢各位.
雄牛 2014-02-13
  • 打赏
  • 举报
回复
引用 1 楼 sololie 的回复:
参考这个 http://pan.baidu.com/s/1sjo83Dj
谢谢, 可以完整的显示了,但是为什么还是操作不了,超出了可视范围外的点? 是不是因为当OnPaint时是复制原图的,并没有对刚操作的点进行复制? 比如,这个Scrollbox1的长高是:500*300,但图是600*400 然后,当加载这个图后,出现了滚动条,之后用上面的代码是可以正常的滚动并查看了. 但是,当我进行操作: pb1.Canvas.Pixels[590,50]:=RGB(0,0,0); 之后滚动条滚动过去查看时,却没看到那个操作的点? 这个有没解决方法的?
星際訪客 2014-02-13
  • 打赏
  • 举报
回复
以樓主的例子...關鍵是使用 TImage.Canvas 當畫布...而不是使用 TPaintBox.Canvas 當畫布...因為 TImage 裡有一個內存位圖與重繪更新機制......
星際訪客 2014-02-11
  • 打赏
  • 举报
回复
同意樓上 sololie 大牛所說的! 組件與控件的使用得依目的情況選定...... sololie 住哪呢? 我這邊也感受到了! 從前天晚上開始...白天氣候涼爽宜人...這個時候我穿了大衣加厚毛襪哩~ 晚安!
sololie 2014-02-11
  • 打赏
  • 举报
回复
赶紧~~
sololie 2014-02-11
  • 打赏
  • 举报
回复
timage 侧重于显示一个图像,内部维护一个TPicture tpaintbox 侧重于绘图,故提供了OnPaint消息,对于绘图操作更灵活高效 当然,各自的优劣取决于需求的定位,如果仅仅是显示一个图像而没有其他更多的工作,那image更适合。 如果还要对一个图形进行各种处理,那么piantbox是更好的选择 这两天冷空气南下,受不了了,都感觉钻被窝去吧
星際訪客 2014-02-11
  • 打赏
  • 举报
回复
引用 3 楼 sololie 的回复:
LZ只是搞不清楚paintbox要绘制的rect,搞清楚就可以了,paintbox一样的。 用image有image的好处,paintbox有paintbox的好处,一般需要做大量绘图操作的用paintbox效率更高。 btw~~ LS夜猫子跟俺堪有一比啊
當夜貓子也不是我願意呀~ 經常為了搞案子把生理時鐘給弄亂了呀!
星際訪客 2014-02-11
  • 打赏
  • 举报
回复
實務上...TImage 內部的重繪機制已處理...所以可以完全取代 TPaintBox 而更方便!
sololie 2014-02-11
  • 打赏
  • 举报
回复
LZ只是搞不清楚paintbox要绘制的rect,搞清楚就可以了,paintbox一样的。 用image有image的好处,paintbox有paintbox的好处,一般需要做大量绘图操作的用paintbox效率更高。 btw~~ LS夜猫子跟俺堪有一比啊
星際訪客 2014-02-11
  • 打赏
  • 举报
回复
因為 PaintBox1 的 Canvas 並不能夠永遠安全的顯示...因為只要被覆蓋就會消失...通常窗口只要有更新事件便需要重繪才能顯示出來...但...這個問題並不會發生在 Image1 上...... Step 1: 改變作法...先將 PaintBox1 除去...再把 Image1 放在 ScrollBox1 裡. Step 2:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.AutoSize := True;
  Image1.Left := 0;
  Image1.Top := 0;
  ScrollBox1.HorzScrollBar.Tracking := True;
  ScrollBox1.VertScrollBar.Tracking := True;
end;
Step 3:
procedure TForm1.Button4Click(Sender: TObject);
begin
  if OpenPictureDialog1.Execute then
    if FileExists(OpenPictureDialog1.FileName) then
      Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName)
    else
      raise Exception.Create('圖檔不存在.');
end;
sololie 2014-02-11
  • 打赏
  • 举报
回复

5,943

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧