1. 程式人生 > >實現AlphaBlend混合實現透明的程式碼

實現AlphaBlend混合實現透明的程式碼

實現AlphaBlend混合的程式碼.
主要的演算法是:
r = (BYTE)((((rForeground - rBackground)*delta) >> ALPHA) + rBackground);
g = (BYTE)((((gForeground - gBackground)*delta) >> ALPHA) + gBackground);
b = (BYTE)((((bForeground - bBackground)*delta) >> ALPHA) + bBackground);


下面是具體實現。(程式碼可成功執行)

// 一共2^8 + 1個等級,0為透明,256為不透明,中間的值為半透明
#define ALPHA 8
#define FRAMEPENWIDTH 2 // 文字框的寬度
#define FRAMECOLOR RGB(192,192,192) // 文字框的顏色
#define SHADOWWIDTH 1 // 陰影的寬度(為了有立體感)
#define SHADOWCOLOR RGB(0,0,0) // 陰影的顏色
#define TEXTCOLOR RGB(0,0,192) // 文字的顏色
// 文字框的寬度預設100畫素,寬度、高度可以動態調整
#define DEFAULTOUTPUTWIDTH 100

VOID ShowTransparentText(
HWND hDstWnd, // 在那個視窗透明顯示
DWORD Alpha, // Alpha通道值(0 < Alpha < 256)
COLORREF crForeground, // 文字框底色
LPCTSTR lpszTxt, // 文字
DWORD dwDelayTime // 顯示多長時間
)
{
COLORREF crBackground;
BYTE r, g, b;
BYTE rBackground, gBackground, bBackground;
BYTE rForeground, gForeground, bForeground;
INT x, y;
INT nDstPosX, nDstPosY;
INT nWidth, nHeight;
HDC hWorkDC, hSaveDC, hDstDC;
HANDLE hBitmap, hBitmap2;
HFONT hf, hfSave;
LOGFONT lf;
RECT rect;
DWORD delta;

//建立文字框字型
lf.lfHeight = 14;
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_NORMAL; //FW_BOLD
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = 0;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
_tcscpy(lf.lfFaceName, TEXT("Tahoma"));

VERIFY(hf = CreateFontIndirect(&lf));

hDstDC = GetDC(hDstWnd);

hWorkDC = CreateCompatibleDC(hDstDC);

hfSave = (HFONT)SelectObject(hWorkDC, hf);
nWidth = DEFAULTOUTPUTWIDTH;
nHeight = DEFAULTOUTPUTWIDTH;
SetRect(&rect, 0,0,nWidth,nHeight);
DrawText(hWorkDC, lpszTxt, lstrlen(lpszTxt), &rect, DT_CALCRECT|DT_LEFT|DT_WORDBREAK);

// 自畫立體邊框
nWidth = rect.right - rect.left + (FRAMEPENWIDTH + SHADOWWIDTH) * 2;
nHeight = rect.bottom - rect.top + (FRAMEPENWIDTH + SHADOWWIDTH) * 2;

hBitmap = CreateCompatibleBitmap(hDstDC, nWidth, nHeight);
SelectObject(hWorkDC, hBitmap);

hSaveDC = CreateCompatibleDC(hDstDC);
hBitmap2 = CreateCompatibleBitmap(hDstDC, nWidth, nHeight);
SelectObject(hSaveDC, hBitmap2);


GetClientRect(hDstWnd, &rect);
nDstPosX = rect.left + (rect.right - rect.left - nWidth)/2;
nDstPosY = rect.top + (rect.bottom - rect.top - nHeight)/2;
BitBlt(hWorkDC, 0, 0, nWidth, nHeight, hDstDC, nDstPosX, nDstPosY, SRCCOPY);
BitBlt(hSaveDC, 0, 0, nWidth, nHeight, hDstDC, nDstPosX, nDstPosY, SRCCOPY);

delta = Alpha%(1<<ALPHA); // 假若Alpha的值操作256,取模

// 因為0 , 256 對256取模都為0, 但是0為透明,256為不透明
if((0 == delta) && (Alpha == (1<<ALPHA)))
{
delta = Alpha;
}

rForeground = GetRValue(crForeground);
gForeground = GetGValue(crForeground);
bForeground = GetBValue(crForeground);

for(y = SHADOWWIDTH + SHADOWWIDTH; y< (nHeight - (SHADOWWIDTH + SHADOWWIDTH)); y++)
{
for(x = SHADOWWIDTH + SHADOWWIDTH; x < (nWidth - (SHADOWWIDTH + SHADOWWIDTH)); x++)
{
crBackground = GetPixel(hWorkDC, x, y);

rBackground = GetRValue(crBackground);
gBackground = GetGValue(crBackground);
bBackground = GetBValue(crBackground);

r = (BYTE)((((rForeground - rBackground)*delta) >> ALPHA) + rBackground);
g = (BYTE)((((gForeground - gBackground)*delta) >> ALPHA) + gBackground);
b = (BYTE)((((bForeground - bBackground)*delta) >> ALPHA) + bBackground);

SetPixel(hWorkDC, x, y, RGB(r,g,b));
}
}

// 由於Smartphone不提供FrameRect函式,所以自行實現該功能。
// 畫出外框
for(y = 0; y< FRAMEPENWIDTH; y++)
{
for(x = 0; x < nWidth; x++)
{
SetPixel(hWorkDC, x, y, FRAMECOLOR);
SetPixel(hWorkDC, x, nHeight - y - 1, FRAMECOLOR);
}
}

for(x = 0; x< FRAMEPENWIDTH; x++)
{
for(y = 0; y < nHeight; y++)
{
SetPixel(hWorkDC, x, y, FRAMECOLOR);
SetPixel(hWorkDC, nWidth - x -1, y, FRAMECOLOR);
}
}

// 畫出陰影框
for(y = FRAMEPENWIDTH; y< (FRAMEPENWIDTH+SHADOWWIDTH); y++)
{
for(x = FRAMEPENWIDTH; x < (nWidth - FRAMEPENWIDTH); x++)
{
SetPixel(hWorkDC, x, y, SHADOWCOLOR);
SetPixel(hWorkDC, x, nHeight - y - 1, SHADOWCOLOR);
}
}

for(x = FRAMEPENWIDTH; x< (FRAMEPENWIDTH+SHADOWWIDTH); x++)
{
for(y = FRAMEPENWIDTH; y < (nHeight - FRAMEPENWIDTH); y++)
{
SetPixel(hWorkDC, x, y, SHADOWCOLOR);
SetPixel(hWorkDC, nWidth - x -1, y, SHADOWCOLOR);
}
}

// 輸出透明字
SetRect(&rect, (FRAMEPENWIDTH+SHADOWWIDTH), (FRAMEPENWIDTH+SHADOWWIDTH), nWidth - (FRAMEPENWIDTH+SHADOWWIDTH), nHeight - (FRAMEPENWIDTH+SHADOWWIDTH));
SetBkMode(hWorkDC, TRANSPARENT);
SetTextColor(hWorkDC, TEXTCOLOR);
DrawText(hWorkDC, lpszTxt, lstrlen(lpszTxt), &rect, DT_LEFT|DT_WORDBREAK);
BitBlt(hDstDC, nDstPosX, nDstPosY, nWidth, nHeight, hWorkDC, 0, 0, SRCCOPY);
DeleteObject(SelectObject(hWorkDC, hfSave));
DeleteObject(hBitmap);
DeleteDC(hWorkDC);

// 延遲制定時間,最好用WaitForSingleObject, 這樣使用者既可以終止等待,SetEvent即可
// 或者超時,即相當於Sleep功能
Sleep(dwDelayTime);

// 恢復原來的背景
BitBlt(hDstDC, nDstPosX, nDstPosY, nWidth, nHeight, hSaveDC, 0, 0, SRCCOPY);
DeleteObject(hBitmap2);
DeleteDC(hSaveDC);

ReleaseDC(hDstWnd, hDstDC);

相關推薦

實現AlphaBlend混合實現透明程式碼

實現AlphaBlend混合的程式碼. 主要的演算法是: r = (BYTE)((((rForeground - rBackground)*delta) >> ALPHA) + rBackground); g = (BYTE)((((gForeground -

Direct3D進行Alpha混合實現透明效果

這次給大家奉獻的是我最近學習DirectX基礎的一些內容:進行Alpha混合。雖然我在很多的遊戲中看到了美輪美奐的半透明效果,但是能夠自己製作出半透明的效果還是一件非常欣慰的事情。因為這不僅僅是自己目的的達成,還是自己自學能力的提升。 Alpha是畫素顏色中的一個值,但

MFC + CxImage 實現自繪半透明按鈕

processor 專用 win dword ssa ont false set 技術 btn.h [cpp] view plain copy #pragma once // CBtn #include "ximage

C#實現中英文混合字符串截取的方法

i++ -a 調用 ati col 委托 一個 thum div 本文實例講述了C#實現中英文混合字符串截取的方法,是C#字符串操作中非常常用的一個方法。分享給大家供大家參考之用。具體方法如下: 具體功能代碼如下:/// <summary> /// 截取中英文

mysql+spring+mybatis實現資料庫讀寫分離[程式碼配置]

場景:一個讀資料來源一個讀寫資料來源。 原理:藉助spring的【org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource】這個抽象類實現,看名字可以瞭解到是一個路由資料來源的東西,這個類中有一個方法

clipboard.js實現複製功能的示例程式碼

<div  class="coupon-text-wrap"> <span class="coupon-text" id="coupon-text"  > 123456 </span>   <span class="coupon

原生javascript實現檔案上傳功能程式碼

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ini

Tensorflow 反捲積(DeConv)實現原理+ 手寫python程式碼實現反捲積(DeConv)

1、反捲積原理 反捲積原理不太好用文字描述,這裡直接以一個簡單例子描述反捲積。 假設輸入如下: [[1,0,1], [0,2,1], [1,1,0]]  反捲積卷積核如下: [[ 1, 0, 1], [-1, 1, 0], [ 0,-1, 0]]  

Cordova 實現沉浸式(透明)狀態列效果

沉浸式狀態列(Immersive Mode)和透明狀態列(Translucent Bar)。 這兩個概念很多地方的解釋都不是很清晰,所以導致很多人都各有各的認識。所以這裡我也有一個自己的認識,筆者認為沉浸式狀態列也可以說是全屏模式,即隱藏狀態列與導航欄。 而透明狀態列是不隱藏狀態列但是它所呈

Mybatis逆向工程的pojo實現序列化介面的程式碼

這兩天在學習一個分散式的專案--淘淘商城,使用了Alibaba的dubbo作為通訊工具,zookeeper作為register,由於dubbo是基於socket協議的,所以在進行pojo傳輸的時候報了異常,因為pojo沒有實現序列化介面,就無法進行基於二進位制的序列化傳輸。報錯如下:    但是很麻煩的一

Css3實現四種漸變效果程式碼分享

一、八卦圖背景 程式碼: background: radial-gradient(circle at 50% 59%, #D2CAAB 3%, #364E27 4%, #364E27 11%, rgba(54,78,39,0) 12%, rgba(54,78,39,0)) 50px

java mail實現Email的傳送,完整程式碼

package com.sycamore.controller; import java.security.GeneralSecurityException; import java.util.Date; import java.util.Properties; import javax.mail.

java實現自定義異常例項程式碼

此處主要便於對異常類的使用上方便大家理解以一個公約數為例做了一個簡單自定義異常的處理程式碼如下: 如果操作者輸入數字符合要求程式執行,不符合則丟擲錯誤。 package 自定義異常簡單例項; import java.util.Scanner; public class CommonDivisor

實現中英文混合string的逆向輸出

#include <iostream> using namespace std; // 輸入一個字串(包括英文和中文),將其反序輸出, 如: // hello 今天真熱 ---> 熱真天今 olleh int numChar(char c) // English -> 1

類Flask實現前後端互動之程式碼聊天室

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C# WPF實現滑鼠拖動的程式碼

C# WPF實現滑鼠拖動的程式碼片 ///可表示實時拖動 void xxx_PreviewMouseLeftButtonUp(System.Object sender, System.Windows.Input.MouseButtonEventArgs e) { IsMous

Linux c++,用訊號量實現消費者生產者佇列(程式碼可直接通過編譯)

//用訊號量實現的一個消費者生產者佇列, #include <iostream> #include <pthread.h> #include <semaphore.h> #include <errno.h> #include <queue>

用struts2實現 完整版分頁程式碼

1. userPojo.java原始碼 public class FenyePojo { private Integer numsOfPage;// 每頁顯示多少條資料 private Integer page;// 當前顯示第幾頁 private Integer nums;// 總共多少條資料 p

Netty4.1.1實現群聊功能的程式碼詳細解析

學習Netty已經有一段時間了,其實過程也很坎坷。一開始上手就看文件學習,發現根本看不懂,畢竟中介軟體類別的東西比之前學習WEB框架更具有挑戰性。那怎麼辦呢?當然還是需要先熟悉Java NIO,如果通讀(不要求深入理解)相關API文件,即當對NIO存在一個較為清晰的認識後,回過頭來再次學