webgl 圖像處理

webgl 不僅僅可以用來進行圖形可視化, 它還能進行圖像處理

圖像處理2---圖像傳輸

之前已經進行了點和 uv 數據的傳輸

webgl 進行圖形處理的第二步: 傳輸圖片到 GPU

下圖為傳輸圖片並進行相應渲染的結果

對圖像進行模糊處理, 並轉換為數組輸出

處理過程詳解

  1. 加載圖片

    1. 由於加載圖片是异步方法, 因此很多內容都需要寫在加載圖片的回調函數內
    2. 在回調函數中進行傳輸圖片操作
  2. 傳輸圖片到 GPU

    1. 之前傳輸數據的步驟

      1. 創建緩存區
      2. 綁定緩沖區
      3. 向緩存區中寫入內容
      4. 綁定 shader 中的變量
      5. 開始傳輸數據
    2. 現在傳輸圖像的步驟, 類似
      1. 創建材質 Texture ( 對應前面第 1 步 )
      2. y 軸反轉, 這是由於瀏覽器 y 軸向下, 需要矯正
      3. 激活紋理單元 ( 簡單理解為與紋理綁定的 內容, 一個紋理綁定一個紋理單元 )
      4. 綁定 texture ( 對應前面第 2 步)
      5. 配置圖片信息, 兩種, 一種是縮放相關參數, 用來將圖片的寬高置為 2 的幂次方, 一種是圖片內容 ( 對應前面第 3 步)
      6. 傳輸圖片 ( 對應前面第 4,5 步)
  3. 查詢當前像素的上下左右的顏色值並進行平均

    1. 當前節點的 uv 為 vUv, 是一個二維向量, 範圍從 0-1
    2. 由於圖片設置為 200 * 200, 因此可以將 vUv 轉換為具體的像素點比特置, floor(vUv * 200.0)/200.0
    3. 計算周邊點的比特置及像素值
      1. 例如該像素左邊點比特置為, floor(vUv * 200.0 + vec2(-1.0, 0.0)) / 200.0
      2. 像素值為, texture2D(u_Texture, floor(vUv * 200.0 + vec2(-1.0, 0.0)) / 200.0)
  4. 輸出圖像到數組中

    // 將圖片數據加載到 pixels 數組中
    const pixels = new Uint8Array(200 * 200 *4);
    gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    console.log(pixels);

    最後去得到一個 arrayBuffer 數組

下一階段

當前階段對圖片進行像素顆粒的控制, 利用這個思路能實現大部分對圖片的操作

下個階段是輸入一個數組, 在 GPU 中對數組進行計算, 最後得到相應的數值, 加速計算, 充分利用 GPU 並行計算的能力

代碼實現

import Img from "./img/img1.jpg";
// 兩種著色器
const VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute vec2 uv;
varying vec2 vUv;
void main(){
// 進行插值計算
vUv = uv;
gl_Position = a_Position;
}
`; const FSHADER_SOURCE = `
// 片元著色器中一定要聲明精度
precision mediump float;
varying vec2 vUv;
uniform sampler2D u_Texture; // 求平均
vec4 calculate(vec4 color, vec2 vUv){
vec4 tempColor = color;
if(vUv.x != 0.0 && vUv.y != 0.0){
vec4 left = texture2D(u_Texture, floor(vUv * 200.0 + vec2(-1.0, 0.0)) / 200.0);
vec4 right = texture2D(u_Texture, floor(vUv * 200.0 + vec2(1.0, 0.0)) / 200.0);
vec4 top = texture2D(u_Texture, floor(vUv * 200.0 + vec2(0.0, 1.0)) / 200.0);
vec4 bottom = texture2D(u_Texture, floor(vUv * 200.0 + vec2(0.0, -1.0)) / 200.0);
// tempColor.rg = 1.0 * (left.rg + right.rg + top.rg + tempColor.rg + bottom.rg) / 5.0;
tempColor = 1.0 * (left + right + top + tempColor + bottom) / 5.0;
} return tempColor;
} void main(){
vec4 color = texture2D(u_Texture, vUv); color = calculate(color, vUv); gl_FragColor = color;
}
`; init(); function init() {
const canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
document.body.appendChild(canvas); // 獲取 gl 環境
const gl = canvas.getContext("webgl");
if (!gl) {
console.log("Fail to init content");
return;
} // webgl 程序
const programe = gl.createProgram(); // 初始化著色器
initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe); // 發送數據
sendData("a_Position", 2, [-1, 1, -1, -1, 1, -1, 1, 1], gl, programe); sendData("uv", 2, [0, 1, 0, 0, 1, 0, 1, 1], gl, programe); // 加載圖片
loadImage(gl, programe); } // 初始化著色器
function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe) {
// 創建 shader
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
// 綁定資源
gl.shaderSource(vertexShader, VSHADER_SOURCE);
// 編譯著色器
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER, FSHADER_SOURCE);
gl.shaderSource(fragmentShader, FSHADER_SOURCE);
gl.compileShader(fragmentShader); // 常規流程
gl.attachShader(programe, vertexShader);
gl.attachShader(programe, fragmentShader);
gl.linkProgram(programe);
gl.useProgram(programe);
} // 發送數據到 GPU
function sendData(name, size, arr, gl, programe) {
// 獲取地址空間
const variate = gl.getAttribLocation(programe, name);
if (variate < 0) {
console.log(`Failed to get the location of ${name}`);
return;
}
const variates = new Float32Array(arr);
// 1. 創建緩存區
const buffer = gl.createBuffer();
if (!buffer) {
console.log("Failed to create buffer");
}
// 2. 綁定緩存區
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// 3. 向緩沖區中添加數據
gl.bufferData(gl.ARRAY_BUFFER, variates, gl.STATIC_DRAW);
// 4. 將緩沖區與 glsl 中變量綁定
gl.vertexAttribPointer(variate, size, gl.FLOAT, false, 0, 0);
// 5. 開始傳輸
gl.enableVertexAttribArray(variate);
} function loadImage(gl, programe){
// 初始化 Image
const image = new Image();
// 通過 loader 加載圖像路徑
image.src = Img; // 設置回調函數
image.onload = ()=>{
const texture = gl.createTexture();
// y 軸反轉
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
// 激活 0 號紋理單元
gl.activeTexture(gl.TEXTURE0);
// 綁定 texture
gl.bindTexture(gl.TEXTURE_2D, texture);
// 圖像處理, 一定要有, 用來將圖片寬高擴展到 2 的幂
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);// 配置紋理參數
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); // 配置圖片
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // 配置紋理圖像
// 傳輸圖片
const u_Texture = gl.getUniformLocation(programe, "u_Texure");
gl.uniform1i(u_Texture, 0); // 刷新顏色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清除
gl.clear(gl.COLOR_BUFFER_BIT);
// 畫圖形
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); // 將圖片數據加載到 pixels 數組中
const pixels = new Uint8Array(200 * 200 *4);
gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels);
} }

webgl 圖像處理2---圖像傳輸的更多相關文章

  1. HTML5 學習總結(四)——canvas繪圖、WebGL、SVG

    一.Canvas canvas是HTML5中新增一個HTML5標簽與操作canvas的javascript API,它可以實現在網頁中完成動態的2D與3D圖像技術.<canvas> 標記和 ...

  2. 共有31款PHP 圖形/圖像處理開源軟件(轉)

    詳情點擊:http://www.oschina.net/project/lang/22/php?tag=141&os=0&sort=view PHP 圖像處理庫 Grafika Gra ...

  3. canvas繪圖、WebGL、SVG

    目錄 一.Canvas 1.1.創建canvas元素 1.2.畫線 1.3.繪制矩形 1.4.繪制圓弧 1.5.繪制圖像 1.6.繪制文字 1.7.隨機顏色與簡單動畫 二.WebGL 2.1.HTML ...

  4. HTML5 學習筆記(四)——canvas繪圖、WebGL、SVG

    一.Canvas canvas是HTML5中新增一個HTML5標簽與操作canvas的javascript API,它可以實現在網頁中完成動態的2D與3D圖像技術.<canvas> 標記和 ...

  5. DICOM醫學圖像處理:DIMSE消息發送與接收“大同小异”之DCMTK fo-dicom mDCM

    背景: 從DICOM網絡傳輸一文開始,相繼介紹了C-ECHO.C-FIND.C-STORE.C-MOVE等DIMSE-C服務的簡單實現,博文中的代碼給出的實例都是基於fo-dicom庫來實現的,原因只 ...

  6. Canvas繪圖方法和圖像處理方法(轉)

    轉自:http://javascript.ruanyifeng.com/htmlapi/canvas.html 概述 Canvas API(畫布)用於在網頁實時生成圖像,並且可以操作圖像內容,基本上它 ...

  7. 開源免費跨平臺opengl opencv webgl gtk blender, opengl貼圖程序

    三維圖形的這是opengl的强項,大型3D遊戲都會把它作為首選.圖像處理,是opencv的鎖定的目標,大多都是C的api,也有少部分是C++的,工業圖像錶現,圖像識別,都會考慮opencv的.webg ...

  8. HTML學習總結(四)【canvas繪圖、WebGL、SVG】

    一.Canvas canvas是HTML5中新增一個HTML5標簽與操作canvas的javascript API,它可以實現在網頁中完成動態的2D與3D圖像技術.<canvas> 標記和 ...

  9. FPGA與數字圖像處理技術

    數字圖像處理方法的重要性源於兩個主要應用領域: 改善圖像信息以便解釋. 為存儲.傳輸和錶示而對圖像數據進行處理,以便於機器自動理解. 圖像處理(image processing): 用計算機對圖像進行 ...

  10. webGL之three.js入門2

    入門建議: webGL中文翻譯教程,基於NeHe的openGL教程:http://www.hiwebgl.com/?p=42 . WebGL中文網 http://www.hewebgl.com/ ,裏 ...

隨機推薦

  1. IOS- DocumentInteraction Controllerl的使用

    iOS提供了使用其他app預覽文件的支持,這就是Document Interaction Controller.此外,iOS也支持文件關聯,允許其他程序調用你的app打開某種文件.而且,從4.2開始, ...

  2. maven nexus 3 third party 構件上傳

    mvn -e deploy:deploy-file -DgroupId=com.oracle -DartifactId=JDBCDriver -Dversion=12.0.1 -Dpackaging= ...

  3. jQuery實戰讀書筆記(備忘錄)

    選擇器備忘: | :even 匹配所有索引值為偶數的元素,從 0 開始計數 :odd 匹配所有索引值為奇數的元素,從 0 開始計數 實例——設置table交替行變色: <script type= ...

  4. C 再識數組指針 指針數組的概念

    參考出處: http://www.cnblogs.com/mq0036/p/3382732.html http://www.cnblogs.com/hongcha717/archive/2010/10 ...

  5. HiHocoder1419 : 後綴數組四&#183;重複旋律4&amp;[SPOJ]REPEATS:Repeats

    題面 Hihocoder Vjudge Sol 題目的提示說的也非常好 我對求\(LCP(P - L + len \% l, P + len \% L)\)做補充 \(len=LCP(P, P + L ...

  6. swap分析及其使用

    什麼是swap swap主要是在內存不够用的時候,將部分內存上的數據交換到swap空間上,以便讓系統不會因為內存不够用而導致oom或者更致命的情况出現.當內存使用存在壓力的時候,開始觸發內存回收行為, ...

  7. 蘋果“抄襲”雷軍PPT?小米高管如此評論

    3月26日淩晨,蘋果如期舉行了春季發布會,但發布會上並沒有發布任何新硬件,主角全部是電視.遊戲.信用卡等軟件新品,值得一提的是,在蘋果PPT上,有一張將硬件/軟件/服務三部分單獨提煉出來. “抄襲”雷 ...

  8. spring boot + apache camel 傳輸文件

    一 sftp搭建略 這裏簡單說一下為什麼使用sftp.ftp和sftp各有優點,差別並不是太大.sftp安全性好,性能比ftp低.ftp對於java來說並不複雜,效率也高.之所以使用sftp主要是可以 ...

  9. 在 Ubuntu13.10 服務器中安裝 Munin(監視工具)【轉】

    Munin 監測工具可檢測所有的計算機,並記錄好看到的計算機.通過圖形Web界面的的方式顯示所有信息.重點是即插即用的功能.完成安裝後,大量的控插件會被打. 使用 Munin 您可以輕松地監視您的計算 ...

  10. ACM1001:Sum Problem

    Problem Description In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n.   Input ...