1.獲取上傳圖片對象數據
Javascript無法直接獲取本地上傳的圖片的數據,html5可以解決這一問題 。html5裏面的FileReader interface可以把圖片對象的數據讀到內存,然後通過接口的進度事件(Progress Events)訪問這些數據。
瀏覽器支持:
Internet Explorer: 10+
Firefox: 10+
Chrome: 13+
Opera: 12+
Safari: partial
代碼片段:
var reader = new FileReader(); //建立一個FileReader接口
reader.readAsDataURL(fileBtn.files[0]); //fileBtn爲文件上傳控件對象
reader.onload = function () { //在onload事件中訪問圖像數據
img. reader.result; }
2.獲取圖像對象像素點
圖像對象的getImageData
方法返回一個對象,每個像素點的 rgba
值都保存在其 data
屬性下面,這是一個一位數組, 也就是說,rgba
分別對應一個值,然後接着就是一下像素點的 rgba
,假設 getImageData.data
的值爲 [1,2,3,4,5,6,7,8]
, 那麼 getImageData
對象範圍就包含了 2 個像素點,第一個像素點的 rgba
值分別是 1,2,3,4
,第二個像素點的就是 4,5,6,7,8
。 因此,我們在取每個像素點的 rgba
值的時候其index
應該在像素點的索引值上乘以 4
,然後通過 getGray()
計算灰度。
var imgData = c.getImageData(0, 0, img.width, img.height);
var imgDataArr = imgData.data;
var imgDataWidth = imgData.width;
var imgDataHeight = imgData.height;
for (h = 0; h < imgDataHeight; h += 12) {
for (w = 0; w < imgDataWidth; w += 6) {
var index = (w + imgDataWidth * h) * 4;
var r = imgDataArr[index + 0];
var g = imgDataArr[index + 1];
var b = imgDataArr[index + 2];
}
}
3.根據rgb值計算灰度
不同的RGB空間,灰階的計算公式有所不同,常見的幾種RGB空間的計算灰階的公式如下:
1、簡化 sRGB IEC61966-2.1 [gamma=2.20]
Gray = (R^2.2 * 0.2126 + G^2.2 * 0.7152 + B^2.2 * 0.0722)^(1/2.2)
2、 Adobe RGB (1998) [gamma=2.20]
Gray = (R^2.2 * 0.2973 + G^2.2 * 0.6274 + B^2.2 * 0.0753)^(1/2.2)
3、Apple RGB [gamma=1.80]
Gray = (R^1.8 * 0.2446 + G^1.8 * 0.6720 + B^1.8 * 0.0833)^(1/1.8)
4、ColorMatch RGB [gamma=1.8]
Gray = (R^1.8 * 0.2750 + G^1.8 * 0.6581 + B^1.8 * 0.0670)^(1/1.8)
5、簡化 KODAK DC Series Digital Camera [gamma=2.2]
Gray = (R^2.2 * 0.2229 + G^2.2 * 0.7175 + B^2.2 * 0.0595)^(1/2.2)
// 根據rgb值計算灰度
function getGray(r, g, b) {
return 0.299 * r + 0.578 * g + 0.114 * b;
}
4.根據灰度生成相應字符
把不同的灰度替換成相應的字符,原則上灰度越深的像素應該用越複雜的字符,具體什麼字符可以自由替換,這只是一個測試版本。
代碼片段:
// 根據灰度生成相應字符
function toText(g) {
if (g <= 30) {
return ’8′;
} elseif (g > 30 && g <= 60) {
return ’&’;
} elseif (g > 60 && g <= 120) {
return ’$';
} elseif (g > 120 && g <= 150) {
return ’*';
} elseif (g > 150 && g <= 180) {
return ’o';
} elseif (g > 180 && g <= 210) {
return ’!';
} elseif (g > 210 && g <= 240) {
return ’;';
} else {
return‘.’;
}
}
到這次我們的工作就完成得差不多啦,上面只給出了一些代碼的片段,把原理疏通了一下,具體怎麼實現大家可以自由發揮,下面給出一個示例,把源碼也貼出來跟大家分享。
PS:已經把這個demo整合到我博客的小工具裏了(通過模板實現)去看看?