Private Declare Function BitBlt Lib "gdi32" Alias "BitBlt" _
   (ByVal hDestDC As Long,  _
    ByVal x As Long,  _
    ByVal y As Long,  _
    ByVal nWidth As Long,  _
    ByVal nHeight As Long,  _
    ByVal hSrcDC As Long,  _
    ByVal xSrc As Long,  _
    ByVal ySrc As Long,  _
    ByVal dwRop As Long _
   ) As Long

解决方案 »

  1.   

    bitblt好像不能进行局部放大吧
    用StretchBlt在不放大时比PaintPicture速度还慢,不过,放大时倒是比PaintPicture有长足的进步
      

  2.   

    Private Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As LonghDestDC: 目标设备场景 
    x,y: 目标矩形左上角的x,y坐标 
    nWidth,nHeight: 目标矩形的宽度和高度 
    hSrcDC: 源设备场景 
    xSrc,ySrc: 源矩形左上角的x,y坐标  
    dwRop: 传输过程中进行的光栅运算调用例:(假定图像从PictureBox传输至Form,W,H为目标矩形的宽度和高度)BitBlt hDC,0,0,W,H,Picture1.hDC,0,0,vbSrcCopy 
      

  3.   

    用BitBlt如何将中间的一段区域进行放大呢
      

  4.   

    若放大后还要平移,建议你先用StretchBlt或PaintPicture将源图像放大,然后再用BitBlt平移图像
      

  5.   


    StretchBlt VB声明 
    Declare Function StretchBlt Lib "gdi32" Alias "StretchBlt" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long 
    说明 
    将一幅位图从一个设备场景复制到另一个。源和目标DC相互间必须兼容。这个函数会在设备场景中定义一个目标矩形,并在位图中定义一个源图象。源矩形会根据需要进行伸缩,以便与目标矩形的大小相符 
    返回值 
    Long,非零表示成功,零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    hdc Long,目标设备场景 
    x,y Long,目标矩形左上角的x,y坐标,以逻辑坐标表示 
    nWidth,nHeight Long,目标矩形的宽度和高度,以逻辑坐标表示 
    hSrcDC Long,源设备场景。如光栅运算未指定一个源,则这个参数应为零 
    xSrc,ySrc Long,用源DC的逻辑坐标表示的源矩形左上角位置 
    nSrcWidth,nSrcHeight Long,分别指定用逻辑单位(以源DC为基础)传输的一幅图象的宽度和高度。如其中有一个参数的符号(指正负号)与对应的目标参数不符,位图就会在对应的轴上作镜像转换处理 
    dwRop Long,传输过程中进行的光栅运算。如刷子属于光栅运算的一部分,就使用选入目标DC的刷子 
    注解 
    可用GetDeviceCaps函数判断特定的设备场景是否支持此函数
    不可选择对源位图进行剪切或旋转处理,源位图也不能是一个图元文件设备场景补充:StretchBlt放大图像时速度很慢,所以应先放大后平移。StretchBlt函数说明摘自zyl910(910:分儿我来了!)的贴子。
      

  6.   

    用PaintPicture或Stretchblt进行放大,再用Bitblt平移。
    不过,好像只有Form和PictureBox能够用PaintPicture
    如果用Form进行放大后,然后用什么图形句柄来保存放大后的图形呢,用Picture对象行不行呢?(这个目标hdc实在有些折熬我这只菜鸟)如果图形已经放大了,但又如何在屏幕上用平移方法来显示指定区域的图象呢
      

  7.   

    VB可以使用DirectX,你可以去MS下载DirctXSDK,里面有大量的VB例程
      

  8.   

    我怕我会用DirectX7.0时,我这个程序都快成老太婆了,
    不知就用PaintPicture和Bitblt能不能将这个问题较完满的解决一下。
    ================================================================CSDN 论坛助手 Ver 1.0 B0402提供下载。 改进了很多,功能完备!★  浏览帖子速度极快![建议系统使用ie5.5以上]。 ★  多种帖子实现界面。 
    ★  保存帖子到本地[html格式]★  监视您关注帖子的回复更新。
    ★  可以直接发贴、回复帖子★  采用XML接口,可以一次性显示4页帖子,同时支持自定义每次显示帖子数量。可以浏览历史记录! 
    ★  支持在线检测程序升级情况,可及时获得程序更新的信息。★★ 签名  ●  
         可以在您的每个帖子的后面自动加上一个自己设计的签名哟。Http://www.ChinaOK.net/csdn/csdn.zip
    Http://www.ChinaOK.net/csdn/csdn.rar
    Http://www.ChinaOK.net/csdn/csdn.exe    [自解压]
      

  9.   

    要提高图像的浏览速度,呵呵,一个大家公认的方法就是:把图像缓冲到内存。而在输出图像的时候,采用API直接操控内存,这才是提高速度之道啊.
      

  10.   

    把图像缓冲到内存。而在输出图像的时候,采用API直接操控内存,这才是提高速度之道啊.我也想这么做呀,不过,有些东西还不知道,也不会用,还请指教!
      

  11.   

    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long'w0,h0为源图像的宽、高 w1,h1为放大后图像的宽、高。
    Dim hMem0 As Long, hbitmap0 As Long, holdmap As Long
    Dim pic As PictureSet pic = LoadPicture("图像文件")
    'hMem0保存源图像,hmem1保存过渡图像
    hMem0 = CreateCompatibleDC(hdc)
    holdmap = SelectObject(hMem0, pic.Handle)
    If holdmap <> 0 Then DeleteObject holdmap'将源图像转移到过渡DC中
    hMem1 = CreateCompatibleDC(hdc)
    hbitmap1 = CreateCompatibleBitmap(hdc, w1, h1)
    holdmap = SelectObject(hMem1, hbitmap1)
    If holdmap <> 0 Then DeleteObject holdmap
    StretchBlt hMem1, 0, 0, w1, h1, hMem0, 0, 0, w0, h0, vbSrcCopy
    '改变w1, h1,w0, h0,即可改变放大比率时(放大比率=1,即不放大)'平移时:
    BitBlt hdc, x, y, w, h, hMem1, X1, Y1, vbSrcCopy
    'x,y,w,h:屏幕矩形
    'x1,y1欲显示区域的左上角坐标
    '所谓平移即是改变x,y,或x1,y1的值'改变比率时:
    hbitmap1 = CreateCompatibleBitmap(hdc, w2, h2)
    holdmap = SelectObject(hMem1, hbitmap1)
    If holdmap <> 0 Then DeleteObject holdmap'删除存储器DC、Bitmap
    DeleteDC hMem0
    DeleteObject hbitmap0
    DeleteDC hMem1
    DeleteObject hbitmap1
      

  12.   

    哪需要用API函数那么复杂。
    改进算法就可以了。平移的时候不要绘制整个图像,只绘制窗口区域部分的图像。
    用一个StdPicture对象来装载图像,用Form或PictureBox来显示图像。
    适当的时候把StdPicture里的图像裁减出Form或PictureBox那么大一块合适的区域,绘制出来。StdPicture由个method, 可以达到BitBlt效果。不要动不动就API,把简单的事变复杂。
      

  13.   

    就事论事,对于这个任务,StdPicture不见得简单,API不见得复杂。而且由于一些COM的开销,StdPicture会占用更多资源。如果做专门的图像浏览程序,建议使用API,少许复杂性是值得的。如果图像浏览仅仅是附带功能,那么Std对象相对安全一点。
      

  14.   

    '将源图像转移到过渡DC中
    hmem1 = CreateCompatibleDC(Hdc)
    hbitmap1 = CreateCompatibleBitmap(Hdc, w1, h1)
    HoldMap = SelectObject(hmem1, hbitmap1)
    If HoldMap <> 0 Then DeleteObject HoldMap
    StretchBlt hmem1, 0, 0, w1, h1, HMem0, 0, 0, w0, h0, vbSrcCopyBitBlt Hdc, x, y, w, h, hmem1, X1, Y1, vbSrcCopy怎么图形一点都不显示,如果去掉hmem1这个中间环节,倒是能够显示。
    现在的问题是如何让hmem1这个中间环节起作用呢
      

  15.   

    这个问题重点不是在是不是使用API, 而是要改进算法。不要整幅的移动图像。这会消耗大量计算资源。从视觉上考虑,只要在提供一个视觉上平移的效果就可以了。针对性的处理图像的可见部分可以大副提高速度。这只需简单的坐标换算,计算出你要显示的区块,就可以了。
      

  16.   

    with ScreenView        
    FrmPic.PaintPicture PrePic, _
                                .CLeft, _
                                .CTop, _
                                .CWidth, _
                                .CHeight, _
                                mShowView.CLeft, _
                                mShowView.CTop, _
                                mShowView.CWidth, _
                                mShowView.CHeight
    end with
    frmpic为显示图形的窗体
    prepic为保存图形的picture对象
    ScreenView 为一个变形的RECT结构,保存窗体的显示区域
    mShowview为一个变形的RECT结构,保存欲显示的图形的区域(也就是图像的可见部份)
    这样的做法是,每次Paint时,都要进行局部放大,也就是平移和放大处理都是一样的算法。
    但是速度还是尢显不足
      

  17.   

    至于大家提到的先放大,再用Bitblt进行平移,
    可是我却不会将放大的图象保存起来。
    用505教的StretchBlt方法,却无法在Picturebox控件中显示图形,也不知是什么原因,还是,每次调用Bitblt或StretchBlt时都要将它的DC进行删除,不知为什么?
      

  18.   

    也就是
    hbitmap1 = CreateCompatibleBitmap(0, 3000, 2555)
    不成功
    因不知用什么hdc,试过Form.hdc,Picture1.hdc,但就是不成功,始终等于0
      

  19.   

    删除DC是让你不用时释放它。hbitmap1 = CreateCompatibleBitmap(hdc, 3000, 2555)不能成功,hmem1、hbitmap1 是否未定义(我给你的代码里没有)?加上试试。我给你的代码只是一些片段,比如,你要放大时就用StretchBlt的那一段,平移时就用BitBlt的那一段,结束时就加上删除DC的那一段。祝你顺利。
      

  20.   

    现在放大、缩小、平移快成功了,但是一个实际的问题又出来了,怎么彩色图显示不出来了,只是黑白,而且四周一大堆的“棉花”,是不是我创建的CreateCompatibleBitmap是黑白的,那怎么创建彩色的呢?
    我是这样进行放大的:    If HoldMap1 <> 0 Then DeleteObject HoldMap1
        If hMem1 <> 0 Then DeleteDC hMem1
        If hBitMap <> 0 Then DeleteObject hBitMap
        
        hMem1 = CreateCompatibleDC(0)
        hBitMap = CreateCompatibleBitmap(hMem1, mWidth, mHeight)
        HoldMap1 = SelectObject(hMem1, hBitMap)是这样进行平移的
    BitBlt FrmPic.Picture1.Hdc, 0, 0, .Width, .Height, hMem1, x, y, vbSrcCopy
      

  21.   

    Set pic = LoadPicture("图像文件")
    'hMem0保存源图像,hmem1保存过渡图像
    hMem0 = CreateCompatibleDC(hdc)
    holdmap = SelectObject(hMem0, pic.Handle)
    If holdmap <> 0 Then DeleteObject holdmaphMem1 = CreateCompatibleDC(hdc)
    hbitmap1 = CreateCompatibleBitmap(hdc, w1, h1)
    holdmap = SelectObject(hMem1, hbitmap1)
    If holdmap <> 0 Then DeleteObject holdmap
    '将源图像转移到过渡DC中
    StretchBlt hMem1, 0, 0, w1, h1, hMem0, 0, 0, w0, h0, vbSrcCopy
    ===========================================================
    '改变比率时需将源图放大至hmem1
    hbitmap1 = CreateCompatibleBitmap(hdc, w2, h2)
    holdmap = SelectObject(hMem1, hbitmap1)
    If holdmap <> 0 Then DeleteObject holdmap
    StretchBlt hMem1, 0, 0, w2, h2, hMem0, 0, 0, w0, h0, vbSrcCopy
    只要比率不变就不要动hmem1了.平移时只需要bitblt就可以了
    BitBlt FrmPic.Picture1.Hdc, 0, 0, .Width, .Height, hMem1, x, y, vbSrcCopy 
    =================================================================你的问题在于创建了放大的hmem1后没有把hmem0的图像传输过来.
      

  22.   

    picture1.picture=loadpicture("filename")时是彩色的吗?
    BitBlt FrmPic.Picture1.Hdc, 0, 0, .Width, .Height, hMem0, x, y, vbSrcCopy时是彩色的吗?
      

  23.   

    非常感谢,也就是在创建位图资源时
     hBitMap = CreateCompatibleBitmap(hdc, mWidth, mHeight)
    hdc应该和原始图的hdc一致,
    将hdc改成hmem0就行了,不过,好像缩放的速度又下降了一些,不过,平移时不出问题就行了,
    好了,等我将它完整的做出来,我再来感谢大家吧,特别是505(差点成502了)
      

  24.   

    好了,这个问题暂时主就这样处理吧
    对于VB中的图象处理,可以用PaintPicture和Strpicture的Render进行缩放,
    平移,其效率还高以,如果不是很挑剃的话,这种速度还算比较均衡,放大、缩小、平移其实都是一种操作,就是将原始图形欲显示的部份PaintPicture到目标窗口(Form或Pictrue)上。
    当然VB中还可以用Picture的AutoSize和Image的Stretch进行缩放、平移处理。还可以用PictureClip的Clip属性获得要显示的区域图象。
    上面的方法我基本上都用过,特别是PaintPicture,也就是在本问题提出的那样,在平移时,如果鼠标不是飞快的跑的话,那效果还算可以。
    最终我还可根据大家提出的用API函数进行处理,用API函数进行处理,在缩放时,因为要将一幅图完整的进行缩放,其速度是很慢的,不过,平移时效果很好,也就是说StretchBlt效率很差,但是Bitblt的效率却是很高的,对于这个API函数的预读、预处理,都要用StretchBlt这个函数进行,不知哪能位高手能指教一下,如何进行预读处理,而且资源怎么进行分配时,效果比较佳。
    至于用DirectX进行图象处理,我只知在玩游戏时,用DirectX进行处理时,应该效果不错吧。因为时间有限,以及知道的缺陷,我也只有在以后和大家探讨了
    至于那些什么专业术语OpenGl,GDI,什么的,小弟就什么都不知了。好了,我要结贴了。
    谢谢大家的帮助