使用GDI 進行開發的一些問題(9)

2021-08-27 09:31:39 字數 4374 閱讀 3696

影象的本質是什麼?對不同的人來說這是不同的東西。在計算機的世界中,啥東西都是資料,影象也是一種資料。從自然界的光變成計算機的資料,需要通過取樣和量化的處理。影象在計算機中,其實是乙個二維陣列,從數學上來說,這其實是乙個矩陣。影象中的每乙個點都是個四維向量,也就是(r,g,b,a), 在rgba色彩空間中,我們可以使用乙個矩陣對每乙個點(r,g,b,a)作矩陣乘法運算,這樣就可以對影象色彩進行變換。這種做法其實是從三維空間座標系中的仿射變換類推過來的。具體關於仿射變換,可以參考 對於仿射變換的介紹。

色彩矩陣就是這個用來對色彩作仿射變換的矩陣。這是乙個5*5的矩陣,如圖

圖 5色彩空間矩陣

其實和在空間中的仿射變換完全一樣,可以實現縮放,旋轉,平移等功能。我看到網上有個人寫了一篇深入淺出的文章"gdi+ colormatrix的完全揭秘與**實現" 寫得不錯,只是沒有理解到colormatrix應用的精髓。簡單套用了一些什麼顏色剪下,顏色旋轉,顏色平移的概念,這些東西其實在三維空間中很好理解,但是在色彩空間中,就完全不是那麼回事情了,什麼叫做顏色旋轉60度呢? 這東西忽悠人很有用,只是看完了還是不知道怎麼用,有興趣的同學可以去看看。我下面舉幾個例子,說明colormatrix的具體應用。

灰度化是指去除影象的彩色資訊,講所有的色調歸為0,所有的飽和度也歸為零。這個世界上有很多種不同的灰度化的演算法,隨便寫個演算法,弄篇*****搞個碩士畢業應該不成問題,比如說所有的顏色替換成r' = g' = b' = (r+b+g)/3。有一種很通用的灰度化演算法如下,這其實是ntsc的色彩權重。

r'=b'=g' = 0.299*r + 0.587*g + 0.114*b

那如果我們要使用colormatrix, 可以用以下的矩陣:

float

ptsarray =

,new

float

,new

float

,new

float

,new

float };

得到的結果如下:

再引用一下裡的這篇文章 ,如果用他的演算法,那麼矩陣如下

float

ptsarray =

,new

float

,new

float

,new

float

,new

float };

使用colormatrix調整色彩很簡單,用m11對紅色乘乙個係數,用m51對紅色加乙個值,這樣就可以簡單地調整紅色。其他b,g,a通道以此類推。例如下面這個矩陣可以把增加紅色25.5個畫素(如果使用24bppargb):

可以用以下矩陣,將每個通道增加25.5的亮度。

類似的,你可以認為使用以下矩陣,能將每個通道公升高10%的對比度:

很不幸,這是錯的。這個演算法裡面有個關鍵的問題是overflow,如果我們直接使用這個矩陣,你會看到影象上會有溢位,導致你的影象慘不忍睹。我在網上查到有個很髮指的做法可以解決這個問題,雖然發指,但是能解決!就是把最下面的項修正一點點,這樣影象就不溢位了。看下面這個矩陣。

這個矩陣比較複雜,飽和度需要通過不同的色彩權值來修正。我這裡只提供乙個能用的矩陣,具體可以參考這篇*****:

講了那麼多個矩陣,最後讓我們來看看在gdi+裡面colormatrix這個類到底怎麼用:

filestream

fs =

newfilestream

(image,

filemode

.open,

fileaccess

.read);

image

img =

image

.fromstream(fs,

false

,false

);bitmap

bmp =

newbitmap

(img);

img.dispose();

fs.close();

graphics

g =this

.creategraphics();

float

rwgt = 0.3086f;

float

gwgt = 0.6094f;

float

bwgt = 0.0820f;

float

s = 1.2f;

float

ptsarray =

,new

float

,new

float

,new

float

,new

float };

// create a colormatrix

colormatrix

matrix =

newcolormatrix

(ptsarray);

imageattributes

attr =

newimageattributes

();

// set color matrix

attr.setcolormatrix(matrix,colormatrixflag

.default,

coloradjusttype

.default);

// draw image with no affects

g.drawimage(bmp, 0, 0, 200, 150);

// draw image withimageattributes

g.drawimage(bmp,new

rectangle

(205, 0, 200, 150),, 0,bmp.width, bmp.height,

graphicsunit

.pixel, attr);

// dispose

bmp.dispose();

g.dispose();

多少博士大牛在研究這些不同的矩陣以期獲得更強悍的效果。此外還有好多人申請了各種各樣的專利來保護這個色彩變換,所以如果大家想混一篇簡單的*****好畢業,這是個很好的方向。隨便改兩個數字,乙個新的矩陣就出來了,然後版面費一交,就可以發表了。當然,這也是個蠻有意思的題目,可以做很多比較和研究,這些就不是我這種it民工該講的東西了。

使用GDI 進行開發的一些問題(7)

我最近一直在顏色空間中糾結,前面講的透明不透明只是一種特殊的顏色。今天我準備要講的是真正的修正顏色。我們使用的數位相機有不同的型號,感光的ccd效能也是不一樣的,再加上天氣或者周圍光線的原因,我們排出來的 可能會偏色。此外,為了做一些特殊處理,可能需要將 中某乙個特殊的區域顏色進行修正。比如臉色可以...

開發遇到的一些問題

持續更新 1.禁止以複製 貼上以及剪下的方式操作密碼框中的內容 password bind copy cut paste function 2.當頁面取值為乙個字段,但是欄位中有很多資料,用,分割,展示的時候要換行,如何處理?半形的不斷行的空白格 推薦使用 半形的空格 全形的空格 3.比較值時,需要...

SQLite使用的一些問題

1 檢視裡支援as也支援 表名.欄位名 這種寫法 create view 檢視名稱 as select 專案列表.專案id as 序號,專案列表.專案名 as 姓名,屬性分類列表.屬性名 as 屬性名,屬性值列表.屬性值 as 屬性值 from 專案列表,屬性值列表,屬性分類列表 where 屬性值...