zoukankan      html  css  js  c++  java
  • 关于 类似QQ 长截图的方案

    -、屏幕截图:

       长截图时,整个截图界面其实是个异形窗体, 其大体思路是先创建一个半透明的窗体,然后根据截图区域来创建异形窗体。

      异形窗体:

           hRgn :=CreateRectRgn(rt.left,rt.top,rt.right,rt.bottom); //rt为截图区域

           hWndRect:= CreateRgn(0,0,self.width,self.height);

         if CombineRgn(hWndRect,hWndRect,hRgn,Rgn_Xor)<>Error then

          SetWindowRgn(Handle,hWndRect,False);

    二、Hook windows消息

       (1)Hook  WH_MOUSE_LL

            其目的是控制滚动速度,方便截图。同时要将截图区域的滚动条禁用,以免影响连续截图。

         WH_MOUSE_LLProc(icode:integer;w:Wparam;l:Lparam):LRESULT;stdcall

         begin

                   if (icode<0) or (icode<> hc_action) then

                  begin

                          Result:= callNextHookEx(g_mouseWheel_hook,icode,w,l);

                         exit;

                  end; 

                if(w<> WM_MOUSELWHEEL) and( w<>WM_LBUTTONDOWN) and (w<>WM_LBUTTONUP) then

              begin

                       Result:=callNextHookEx(g_mouseWheel_hook,icode,w,l);

                      exit(-1); //返回 <0的值 才能阻止消息进入windows 消息循环。

             end

             mslhook = PMSLLHOOKSTRUCT(l);

            if not assign(mslhook ) then

            begin

                   

                        Result:=callNextHookEx(g_mouseWheel_hook,icode,w,l);

                      exit;

            end

             if( w<>WM_LBUTTOnDOWN) or(W<>WM_LBUttonUp) then exit(-1);

              

            iwheeldelta = short(HiWord(mslhook^.mouseData)); //根据iWheeldelta的值 便可知道 是向上滚动还是向下滚动.

            //控制滚动速度,根据需要,可自行调整

           if i>=3 then

           begin

                                      iTickcount :=GetTickCount;

                                    if iTickount - FtickCount>300 then

                                  begin

                                        //发送消息到主窗体,实现拼图功能

                                       PostMessage(Form.Handle, WM_User+100,iWheelDelta,0);

                                        FTickCount := iTickCount;

                                      i:=0;

                                 end

                                      else

                                     Exit(-1);

          end

         else

         begin

                  inc(i);

                 exit(-1);  

    end

          result :=CallnextHookEx(g_MouseWheel_Hook,icode,w,l);  

        end;

     *(2) 如果想做类似QQ的那种点击截图区域后,可自行滚动截图的功能,还需要Hook , WM_GetMessage.

             在此消息的HookProc  里面自行处理 WM_MouseWheel消息。

    三、拼图

    此部份是最重要的一部份,最简单的做法 是利用 opencv的surf、orb 等算法实现图片拼接。

    参考网址:https://www.cnblogs.com/skyfsm/p/7411961.html

    上述网址只是给出了两张图片的拼接,而且是左右拼接,而我们截图需要的上下拼接,最简单直接的做法就是先将图片旋转90度,拼接完成后再旋转回来

    为了提高效率与准确率,最好使用 “增量拼接'的方式,也就是

     A 与B拼接后 生成Ab,

    当与C拼接时,不要用AB与C拼接,而要使用 b与C拼接生成BC,然后将AB中的B扣掉 合并生成ABC.

    上面的无论surf算法、还是orb算法,都存一个问题。如果 两张图片 有 2个以上的重叠区域时,最后合并生成的图片ABC会有问题。最简单的实验就是去截图带导航栏的门户网站,一试便知。

    仔细分析,我们会发现 具有重叠区域的A、B两张图的拼接,转成数学问题,其本质就是求两个集合的最大交集。

    所以 自写算法如下:

    f b c d g --- list2
    a 0 0 0 0 0
    b 0 1 0 0 0
    c 0 0 2 0 0
    d 0 0 0 3 0
    e 0 0 0 0 0
    f 0 0 0 0 0
    |
    list1

    void max_substring(const std::vector<float> &a1,const std::vector<float> &a2,
    int & max1_index, int & max2_index, int & max_count)
    {
    int len1 = a1.size(); int len2 = a2.size();
    std::vector< std::vector<int16_t> > mat(len1, std::vector<int16_t>(len2));
    max_count = 0; max1_index = 0; max2_index = 0;

    for(int i=0;i<len1;i++)
    for(int j=0;j<len2;j++)
    {
    if(i==0 || j==0) { mat[i][j] = 0; continue; }

    if(fabs(a1[i]-a2[j])<0.5)
    {
    int count = mat[i][j] = mat[i-1][j-1] + 1;
    if(count>max_count) { max_count=count; max1_index=i-count+1; max2_index=j-count+1; }
    }
    else { mat[i][j] = 0; }

    }

    }

    注明:上述算法也有些缺陷,并不满足所有的条件,当图片是 纯 白底、黑字的图片时,也会出现拼图错误,我想这也是QQ长截图有时候也不灵的原因吧。

  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/luisfan/p/14591786.html
Copyright © 2011-2022 走看看