1. 程式人生 > >使用easyx中的putimage函式實現無背景貼圖

使用easyx中的putimage函式實現無背景貼圖

1,待解決的問題

如果我們要在背景圖片貼上小圖片玫瑰花會出現什麼樣的效果

背景圖片
背景圖片顯示異常

玫瑰花
玫瑰花顯示異常

貼圖之後的圖片(玫瑰花圖片我有意縮小,為了與背景看起來融洽些)
載入貼圖後圖片失敗
直接上程式碼:

 #include<graphics.h>
#include <stdio.h>

int main(void)
{
    IMAGE backgroundimg;//儲存背景圖片
    IMAGE flower;       //儲存貼圖
    loadimage(&backgroundimg,_T("E:\\學習\\工程專案\\easyx\\Mipmap\\background.jpg"
));//載入背景圖片 loadimage(&flower,_T("E:\\學習\\工程專案\\easyx\\Mipmap\\flower.jpg"),80,80,true);//載入背景圖片,按指定大小儲存 int width = backgroundimg.getwidth(); int height = backgroundimg.getheight();//獲取長和寬 initgraph(width,height);//根據背景圖片的長和寬初始化視窗,使之鋪滿窗 BeginBatchDraw(); putimage(0,0,&backgroundimg);//在視窗上繪製背景圖片
putimage(190,200,&flower); FlushBatchDraw(); EndBatchDraw(); system("pause"); return 0; }

玫瑰花的黑色部分與背景圖片顯得很不和諧,怎麼去掉黑色部分呢?

解決方法1(掩碼圖法)

方法步驟

    第一步:把玫瑰圖片的掩碼圖(黑白圖)1與背景圖片做與運算。

第二步:把玫瑰圖片(彩色)與第一步運算生成的圖片做或運算(當然彩色玫瑰圖片要與其掩碼圖重疊,
也就是說要貼在背景圖片上的同一個位置)。
這樣就得到了上面貼有瑰花的背景圖

實現原理

顏色在記憶體中表示形式
    EasyX使用24Bit真色彩,用16進位制的顏色表示,形式為0xbbggrr (bb=藍,gg=綠,rr=紅)
    例如,在EasyX中預定義的顏色常量BLACK用十六進位制表示就是0x000000,BLUE:0xAA0000,WHITE:0xFFFFFF,但一個畫素在記憶體中佔4位元組,也就是佔用32位,藍色在記憶體中儲存形式是0x00AA0000,我們沒有必要討論最高位的一個位元組,因為它在任何情況下都是0,只起佔位的作用。我們討論顏色的24位表示形式就夠了。
討論
    第一步:把玫瑰圖片的掩碼圖(黑白圖與背景圖片做與運算.
    與運算想必大家都懂,0^0=0;0^1=0;1^1=1;
    一個畫素在記憶體中是以二進位制數儲存的,所以當一個白色畫素與任意顏色做與運算後得到的是那個任意顏色,任意顏色與黑色做與運算得到的是黑色,想想為什麼。
    所以當一個掩碼圖與背景圖做與運算後會出現什麼效果,就是在背景圖上畫了一個黑色的內容空洞
    第二步:把玫瑰圖片(彩色)與第一步運算生成的圖片做或運算
    或運算:1|1=1,1|0=1,0|0=0;
        彩色玫瑰圖片與背景圖片做或運算時,黑色部分都變成了彩色,也就是,背景圖片的彩色部分替換了玫瑰圖片的黑色部分,玫瑰圖片的彩色部分替換了背景圖片的黑色部分,也就是說,兩張圖片摞在一起,只保留各自的彩色部分。於是就把玫瑰花摳出來貼到背景圖片上了。

詳細步驟

現在我就按照步驟一步一步來實現
我們需要三張圖片,一張背景圖,一張彩色玫瑰花圖,還有一張玫瑰花掩碼圖,我們缺一張掩碼圖。我猜測有製作掩碼圖的工具,大家有興趣可以找一下,現在我就介紹一下如何用EasyX製作掩碼圖。
原理很簡單,先取玫瑰圖片背景(在這張圖片上是黑色)上任意一點,儲存其色值,然後遍歷整章圖片,是此色值的畫素點更改為白色,否則更改為黑色。先說明一點,採取此種方法只適用於需要摳出來的內容裡面沒有或者少量包含與背景色值相同的畫素。否則摳出來的圖片會出現各種漏洞。這是此種方法的侷限性。
下面是製作掩碼圖的程式碼:
DWORD *pmemflower = GetImageBuffer(&flower);
    DWORD *pmemmaskbitmap = GetImageBuffer(&maskbitmap);
    COLORREF maskbk = pmemflower[0];//我確定此點肯定是玫瑰花背景色
    for (int i = 0;i<80*80;i++)
    {
        if (pmemflower[i] <=0x555555&&pmemflower[i] >=0)//0x55555555是深灰色
        {
            pmemmaskbitmap[i]= WHITE;
        }
        else
        pmemmaskbitmap[i]=BLACK;
    }
下面是掩碼圖

這裡寫圖片描述
完整程式碼:

#include<graphics.h>
#include <stdio.h>

int main(void)
{

    IMAGE backgroundimg;//儲存背景圖片
    IMAGE flower;       //儲存貼圖
    IMAGE maskbitmap(80,80); //儲存掩碼
    loadimage(&backgroundimg,_T("E:\\學習\\工程專案\\easyx\\Mipmap\\background.jpg"));//載入背景圖片
    loadimage(&flower,_T("E:\\學習\\工程專案\\easyx\\Mipmap\\flower.jpg"),80,80,true);//載入背景圖片,按指定大小儲存
    int width = backgroundimg.getwidth();
    int height = backgroundimg.getheight();//獲取長和寬
    initgraph(width,height);//根據背景圖片的長和寬初始化視窗,使之鋪滿窗
    DWORD *pmemflower = GetImageBuffer(&flower);
    DWORD *pmemmaskbitmap = GetImageBuffer(&maskbitmap);
    COLORREF maskbk = pmemflower[0];//我確定此點肯定是玫瑰花背景色
    for (int i = 0;i<80*80;i++)
    {
        if (pmemflower[i] <=0x555555&&pmemflower[i] >=0)//0x55555555是深灰色
        {
            pmemmaskbitmap[i]= WHITE;
        }
        else
        pmemmaskbitmap[i]=BLACK;
    }
    BeginBatchDraw();
    putimage(0,0,&backgroundimg);//在視窗上繪製背景圖片
    //putimage(190,200,&maskbitmap);
    putimage(190,200,&maskbitmap,SRCAND);
    putimage(190,200,&flower,SRCPAINT);
     FlushBatchDraw();
     EndBatchDraw();
    system("pause");
    return 0;
}

這裡寫圖片描述

  1. 掩碼點陣圖就是一個黑白點陣圖,黑色部分就是要顯示的部分,白色部分就是要透明的部分經過掩碼運算後,即可將一個位圖的背景色去掉而只保留內容部分 。

相關推薦

使用easyxputimage函式實現背景

1,待解決的問題 如果我們要在背景圖片貼上小圖片玫瑰花會出現什麼樣的效果 背景圖片 玫瑰花 貼圖之後的圖片(玫瑰花圖片我有意縮小,為了與背景看起來融洽些) 直接上程式碼:

javascriptbind()函式實現和應用以及多次bind的結果和引數位置的思考

改變物件方法裡this的值var ob = { name: 'joe', getName: function () { alert(this.name); } }; // 改變getName方法裡原本的this物件為新物件{name: 'haha'} var app = ob.getName.bi

OpenGL顯示背景

轉載請宣告出處:http://blog.csdn.net/xiaoge132/article/details/51448326 導言: 通常在OpenGL裡面繪製的都是預設的黑色背景,對於有些時候,

C#呼叫GDI+1.1函式實現高斯模糊、USM銳化等經典效果。

/// <summary> /// 對影象進行高斯模糊,參考:http://msdn.microsoft.com/en-us/library/ms534057(v=vs.85).aspx /// </summary> /// <

利用C語言函式實現檔案的Copy

2.讀寫   (1).按字元進行讀寫操作   fgetc        int fgetc(FILE *stream);        引數:           @stream 流指標      

android平臺下OpenGL ES 3.0實現2D紋理顯示bitmap

OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E

【遊戲開發】遊戲視窗實現自定義

//Windows視窗標頭檔案 #include <windows.h> //PlaySound函式包含的標頭檔案 #pragma comment(lib,"winmm.lib") //視窗寬度 #define WINDOW_WIDTH 1132 //視窗高度 #define

Qt背景無法失效

Qt的一些使用心得體會 雖然發表出來的都是經過本人測試使用過,但是也會有遺漏之處,望各位諒解以及指出矯正。 1.Qt設計師中對元件進行貼圖時支援png格式圖片,不支援jpg格式圖片;而在程式程式碼中設定元件樣式時支援jpg格式,但是不支援png格式圖片。注:修改圖片字尾名無法改變圖片型別

Unity如何計算帶minimap的資源的大小

format res text tom sum summary returns ati 獲取 /// <summary> /// 計算貼圖大小,包含mipmap內存的疊加 /// </summary> /// <

MFC學習之 背景及控制元件透明

在CDialog類中進行貼圖,一般放在OnPaint()函式中,因為視窗更新時,使用它來進行重繪。在OnPain()中貼圖的原始碼如下: void C***Dialog::OnPaint() { CPaintDC dc(this); // device contex

函式實現返回引數二進位制1的個數;符號的數

int count_one_bits(unsigned int value) #include<stdio.h> //函式返回引數二進位制中1的個數; #include<stdlib.h> // in

基於雙向鏈表實現鎖隊列的正確姿勢(對之前博客錯誤的修正)

單向 reel 規範 特殊 線程 些許 github volatile 時間 目錄 1. 前言 2. 基於雙向鏈表實現的無鎖隊列 2.1 入隊方法 2.2 出隊方法 3. 性能測試 4.總結 1. 前言 如果你認真看過我前幾天寫的這篇博客自己動手構建無鎖的並發容器(棧

編寫一個函式實現數制轉換。在主函式輸人一個十進位制數,輸出相應的十六進位制數。要求用陣列實現

void decto16 (int a, char c[]) {  // a為要轉換的十進位制數 將結果存放在陣列c中 ,以陣列形式輸出   int y;   int k = 0;   do {     y = a % 16;     a = a / 16;     for (int i = 0

PHP實現符號右移(js的 >>>)

tail php art aik http 左移 com 過程 tps 移位包括有符號左移(<<)、有符號右移(>>)、無符號右移(>>>),其中 js 支持三種移位,PHP只支持前兩種移位(沒查到第三種),恰好需要PHP進行

Java程式利用main函式args引數實現引數的傳遞

1.執行Java程式的同時,可以通過輸入引數給main函式中的接收引數陣列args[],供程式內部使用!即當你在Java命令列後面帶上引數,Java虛擬機器就直接把它們存放到了main方法中的引數String數組裡了。 2..args是Java命令列引數,因為引數可以為多個,所以要用陣列來存

續(利用tensorflow實現簡單的卷積神經網路-對程式碼相關函式介紹)——遷移學習小記(三)

  上篇文章對cnn進行了一些介紹,附了完整小例子程式碼,介紹了一部分函式概念,但是對我這樣的新手來說,程式碼中涉及的部分函式還是無法一下子全部理解。於是在本文中將對程式碼中使用的函式繼續進行一一介紹。 具體程式碼見上一篇(二) 一、 #定義輸入的placehoder,x是特徵

(轉)如何在ie6/ie7/ie8實現iframe背景透明

最近做了一個專案,涉及到ie8iframe背景透明的問題,做了老半天,才把它搞定的,現在把我的經歷貼出來和大家分享: 眾所周知的根據W3C CSS 2.1 規範規定,''''background-color'''' 特性的預設值為 ''''transparent''''

[C]C語言函式實現返回引數二進位制 1 的個數

通過C語言程式將十進位制數轉化成二進位制數,然後求出二進位制數中1的個數。 下面用三種方法來實現。來 方法一: 除2取餘法。對一十進位制數,用2輾轉相除至結果為1,將餘數和最後的1從下向上倒序寫就是對應的二進位制。 例如:十進位制數302轉化成二進位制。 302

C++類物件虛擬函式與多型性的實現

在面向物件程式設計時,有時會遇到這種需求:我們希望同一個方法在基類和派生類中實現不同的功能,即體現出行為上的多型性。一般有兩種方法可以實現這種需求,其一是在派生類中重新定義基類中方法,其二是使用虛擬函式。這裡主要記錄利用虛擬函式實現多型性的方法。 類中虛擬函式的定義方法 虛擬函式

的特性、函式實現

類中的特性與函式實現 關於特性 特性定義方法 修飾符 資料型別 變數名; 利用屬性來訪問特性 為什麼需要屬性?通常我們把特性設定為私有變數,一般可以通過函式來進行修改和讀取,需要一個函式來讀取,一個函式來寫。但這樣太麻煩了。 因此有了屬性,屬性本質上