首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Builder 不規則視窗快速建立與顯示技巧

     編輯:關於C++

從位圖快速產生不規則視窗區域

傳統逐像素建立區域 (方法一) 速度極慢。本文提出混合演算法:先雙向掃描建立外框多邊形區域 (方法二),再掃描內部移除凹陷透明區塊,最後取交集,大幅提升建立速度。

三種方法比較

方法原理速度缺點
一、逐像素 XOR白色像素建 1x1 矩形區域 XOR 合併極慢 (4-5 秒)大圖無法接受
二、多邊形外框每列掃描左右邊界建立多邊形快內凹區域無法呈現
三、混合法 (推薦)方法二建外框 + 方法一除內凹 + 取交集快且完整程式較複雜

混合法完整程式碼 (FormCreate)

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    register int x, y;
    int l, r;
    POINT *a;
    bool lb, rb;
    HRGN WndRgn, TempRgn, tepRgn;

    Width = 800; Height = 600; // 初始大小
    if ((a = (POINT*)malloc(800*4*sizeof(POINT))) == NULL) {
        ShowMessage("記憶體配置失敗!"); exit(0);
    }

    Image1->Picture->LoadFromFile(".\\face.bmp");
    Width = Image1->Width; Height = Image1->Height;
    Repaint();

    l = 0; r = Image1->Height * 2 - 1;
    WndRgn = CreateRectRgn(0, 0, Image1->Width, Image1->Height);

    // 步驟 1: 雙向掃描建立外框座標陣列
    for (y = 0; y < Image1->Height; y++) {
        lb = true;
        for (x = 0; x < Image1->Width; x++)
            if (Image1->Canvas->Pixels[x][y] != clWhite) {
                a[l].x = x+1; a[l].y = y; lb = false; break;
            }
        if (lb) a[l] = a[l-1]; l++;

        rb = true;
        for (x = Image1->Width-1; x >= 0; x--)
            if (Image1->Canvas->Pixels[x][y] != clWhite) {
                a[r].x = x; a[r].y = y; rb = false; break;
            }
        if (rb) a[r] = a[r+1]; r--;
    }

    // 步驟 2: 掃描內部白色像素建立小矩形 XOR 移除內凹
    r = Image1->Height * 2 - 1;
    for (y = 0; y < Image1->Height; y++) {
        for (x = a[y].x; x < a[r].x; x++)
            if (Image1->Canvas->Pixels[x][y] == clWhite) {
                tepRgn = CreateRectRgn(x, y, x+1, y+1);
                CombineRgn(WndRgn, WndRgn, tepRgn, RGN_XOR);
                DeleteObject(tepRgn);
            }
        r--;
    }

    // 步驟 3: 外框多邊形區域與現有區域取交集
    TempRgn = CreatePolygonRgn(a, Image1->Height * 2, ALTERNATE);
    CombineRgn(WndRgn, WndRgn, TempRgn, RGN_AND);
    DeleteObject(TempRgn);
    free(a);

    SetWindowRgn(Handle, WndRgn, true);
    SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

準備工作

  1. Photoshop 使用磁性套索抠圖,存為白底 BMP (face.bmp)。
  2. 表單放置 TImage、TPopupMenu (含關閉項目)。

測試環境

Celeron 466, Win98SE/Win2000, C++ Builder 5.0 通過測試。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved