canvas影象畫素處理- 馬賽克/濾鏡(一)
一.要注意的問題
在chrome下會發生錯誤
Uncaught SecurityError:
Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
大概意思就是發生了跨域操作,也就是指圖片的來源和當前的網頁來源不同時,造成了跨域。
據說放到伺服器上載入就會解決這個問題;我放到了本地的伺服器環境可以順利執行。以後凡是用到getImageData函式的地方,一定要使用此方法進行測試,此處不贅述。
二.知識點:
1.圖片的載入:var img=new Image();
img.src = "timg.jpg";
img.onload=function (){
context.drawImage( image , 0 , 0 );
}
2.
①圖片資料讀取完成後,首先將圖片資料繪製到Canvas畫板上,用getImageData函式從畫板上取得畫素資料。
var imgData=context.getImageData(x,y,width,height);
x,y開始複製的起點座標 width,height選擇區域的長和寬
② ImageData 物件,該物件拷貝了畫布指定矩形的畫素資料。最後分析結果:data: 含有ImageData 物件所有的畫素,每個畫素都存在著四個值的資訊,分別是r,g,b,a
這是一個簡單畫素處理:var pixelData = imageData.data;
for(var i=0;i<canvas.width*canvas.height;i++){
pixelData[4*i+0]=0;
pixelData[4*i+1]=0;
// pixelData[4*i+2]=0;
}
這是一個簡單畫素深淺處理:
var pixelData = imageData.data;
for(var i=0;i<canvas.width*canvas.height;i++){var r = pixelData[i*4+0];
var g = pixelData[i*4+1];
var b = pixelData[i*4+2];
var grey = r*0.3+g*0.59+b*0.11;//這個演算法是影象學家研究出對RGB深淺的最好值
pixelData[i*4+0] = grey;
pixelData[i*4+1] = grey;
pixelData[i*4+2] = grey;
}
這是二維陣列:遍歷每一個畫素
for( var i = 0 ; i < canvas.height ; i ++ )
for( var j = 0 ; j < canvas.width ; j ++ ){
//遍歷第i行第j列的時候對應canvas的位移
var p = i*canvas.width + j;
//每一個點的畫素值
pixelData[p*4+0] = r;
pixelData[p*4+1] =g;
pixelData[p*4+2] = b;
}
}
4.putImageData() 方法函式則表示將所得到的畫素資料描畫到Canvas畫板上形成圖形。
context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
其中imgdata為畫素資料,dx、dy是繪製圖片的定位座標值,dirtyX、dirtyY是imgdata所要繪製圖片的起始位置,dirtyXw、dirtyXh是imgdata所要繪製區域(相對imgdata的dirtyXx和dirtyXy座標的偏移量)的寬度和高度值。這裡面第4個引數以及其後的所有引數都可以省略,如果這些引數都省略了,則表示繪製整個imgdata。
5.getImageData函式從畫板上取得畫素資料。然後通過 putImageData() 將所取得的畫素資料畫到Canvas畫板上var imgData=ctx.getImageData(10,10,50,50);
整個畫素資料畫到Canvas畫板上:ctx.putImageData(imgData,10,70);
畫素資料的一部分畫到Canvas畫板上:ctx.putImageData(imgData,200,260,50,50,100,100);
三.特效
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.clearfix:after,.zn-clearfix:before{content: ""; visibility: hidden; display: block; height: 0; clear: both; }
.clearfix{zoom:1;margin: 20px auto; width:1700px;}
</style>
</head>
<body>
<div class="clearfix">
<canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;"></canvas>
<canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;"></canvas>
</div>
<script>
var canvasa = document.getElementById("canvasa");
var contexta = canvasa.getContext("2d");
var canvasb = document.getElementById("canvasb");
var contextb = canvasb.getContext("2d");
var image = new Image();
window.onload = function(){
image.src = "1.jpg";
image.onload = function(){
contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height );
}
}
</script>
</body>
</html>
(1).如何在影象中簡單影象處理灰度濾鏡:
//灰度影響
function greyEffect(){
//通過 getImageData() 複製畫布上指定矩形的畫素資料,然後通過 putImageData() 將影象資料放回畫布:
var imageData = contexta.getImageData(0 , 0 , canvasa.width , canvasa.height);
var pixelData = imageData.data;
for(var i=0;i<canvasb.width*canvasb.height;i++){
var r = pixelData[i*4+0];
var g = pixelData[i*4+1];
var b = pixelData[i*4+2];
var grey = r*0.3+g*0.59+b*0.11;//這個演算法是影象學家研究出對RGB深淺的最好值
pixelData[i*4+0] = grey;
pixelData[i*4+1] = grey;
pixelData[i*4+2] = grey;
}
contextb.putImageData( imageData , 0 , 0 ,0 , 0 , canvasb.width, canvasb.height);
}
黑白濾鏡:是指影象上只有白色,黑色;也就是rgb(255,255,255),或是rgb(0,0,0)。
//黑白濾鏡:是指影象上只有白色,黑色;也就是rgb(255,255,255),或是rgb(0,0,0)。
function blackEffect(){
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var pixelData = imageData.data;
for( var i = 0 ; i < canvasb.width * canvasb.height ; i ++ ){
var r = pixelData[i*4+0];
var g = pixelData[i*4+1];
var b = pixelData[i*4+2];
var grey = r*0.3+g*0.59+b*0.11;
if(grey > 125){
pv = 255;
}
else{
pv = 0;
}
pixelData[i*4+0] = pv;
pixelData[i*4+1] = pv;
pixelData[i*4+2] = pv;
}
contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasa.width , canvasa.height );
}
反色濾鏡:是指影象上的每一個點的RGB值修改為255-原來的值
//反色濾鏡:是指影象上的每一個點的RGB值修改為255-原來的值
function reverseEffect(){
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var pixelData = imageData.data;
for( var i = 0 ; i < canvasb.width * canvasb.height ; i ++ ){
var r = pixelData[i*4+0];
var g = pixelData[i*4+1];
var b = pixelData[i*4+2];
pixelData[i*4+0] = 255 - r;
pixelData[i*4+1] = 255 - g;
pixelData[i*4+2] = 255 - b;
}
contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height );
}
黑白,反色濾鏡的每一個畫素修改只需要參照自己當前的畫素。
要注意:要保證周圍的畫素點不能被演算法所修改,所以就不能僅僅使用一個imageData,需要建立一個imageData的拷貝var tmpImageData.
此後就參考tmpImageData,來修改imageData,最終把imageData結果傳給putImageData,由此複製在畫布上,同時當函式執行putImageData時,tmpImageData也就拋棄了。
模糊濾鏡:模糊濾鏡則需要參考自己周圍的濾鏡,影象上的每一個點的RGB值為周圍的畫素的平均值。
function blurEffect(){
var tmpImageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var tmpPixelData = tmpImageData.data;
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var pixelData = imageData.data;
var blurR =3;//模糊的半徑
//參考多少個畫素點(這個區域是正方形的面積)
var totalnum = (2*blurR + 1)*(2*blurR + 1);
//採用二維迴圈編輯
for( var i = blurR ; i < canvasb.height - blurR ; i ++ ){
for( var j = blurR ; j < canvasb.width - blurR ; j ++ ){
var totalr = 0 , totalg = 0 , totalb = 0;//來計算周圍所有的RGB的總和
//一個畫素點周圍有8個畫素點。
//二維迴圈編輯:基於中心點在x,y方向的位移的變化值,迴圈走了9次,
//下面這個就是點周圍的點迴圈+自身(i,j)
for( var dx = -blurR ; dx <= blurR ; dx ++ ){
for( var dy = -blurR ; dy <= blurR ; dy ++ ){
var x = i + dx;
var y = j + dy;
//周圍畫素點位移
var p = x*canvasb.width + y;
//所對應的畫素點
totalr += tmpPixelData[p*4+0];
totalg += tmpPixelData[p*4+1];
totalb += tmpPixelData[p*4+2];
}
}
//遍歷第i行第j列的時候對應canvas的位移
var p = i*canvasb.width + j;
//把周圍的畫素的平均值賦值(i,j)
pixelData[p*4+0] = totalr / totalnum;
pixelData[p*4+1] = totalg / totalnum;
pixelData[p*4+2] = totalb / totalnum;
}
}
contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height );
}
馬賽克濾鏡:
馬賽克:一塊畫素的值=這塊全部畫素平均值
//馬賽克:一塊畫素的值=這塊全部畫素平均值
function mosaicEffect(){
var tmpImageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var tmpPixelData = tmpImageData.data;
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );
var pixelData = imageData.data;
//定義為一塊的邊長是多少(這個影象寬高的整數倍)
var size = 16;
var totalnum = size*size;
for( var i = 0 ; i < canvasb.height ; i += size )
for( var j = 0 ; j < canvasb.width ; j += size ){
//這塊是計算每一塊全部的畫素值--平均值
var totalr = 0 , totalg = 0 , totalb = 0;
for( var dx = 0 ; dx < size ; dx ++ )
for( var dy = 0 ; dy < size ; dy ++ ){
var x = i + dx;
var y = j + dy;
var p = x*canvasb.width + y;
totalr += tmpPixelData[p*4+0];
totalg += tmpPixelData[p*4+1];
totalb += tmpPixelData[p*4+2];
}
var p = i*canvasb.width+j;
var resr = totalr / totalnum;
var resg = totalg / totalnum;
var resb = totalb / totalnum;
//這個快畫素的值=它的平均值
for( var dx = 0 ; dx < size ; dx ++ )
for( var dy = 0 ; dy < size ; dy ++ ){
var x = i + dx;
var y = j + dy;
var p = x*canvasb.width + y;
pixelData[p*4+0] = resr;
pixelData[p*4+1] = resg;
pixelData[p*4+2] = resb;
}
}
contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width, canvasb.height );
}
相關推薦
canvas影象畫素處理- 馬賽克/濾鏡(一)
一.要注意的問題 在chrome下會發生錯誤Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted
canvas影象畫素處理-createImageData()(二)
一.知識點 3. createImageData函式有兩種函式原型,其語法分別如下所示 (1).createImageData(sw, sh); 其一,返回指定大小的imageData物件。 (
canvas影象處理——實現濾鏡效果
實現濾鏡效果 點選按鈕出現不同濾鏡效果 首先,我們分析濾鏡的具體,主要就是對圖片的每個具體畫素進行處理,先拿到畫素,處理後再將畫素放回去。 1.怎樣拿到畫素
python數字影象處理(3):影象畫素的訪問與裁剪
圖片讀入程式中後,是以numpy陣列存在的。因此對numpy陣列的一切功能,對圖片也適用。對陣列元素的訪問,實際上就是對圖片畫素點的訪問。 彩色圖片訪問方式為: img[i,j,c] i表示圖片的行數,j表示圖片的列數,c表示圖片的通道數(RGB三通道分別對應0,1
Python-OpenCV 處理影象(三):影象畫素點操作
https://segmentfault.com/a/1190000003742442 0x01. 畫素 有兩種直接操作圖片畫素點的方法: 第一種辦法就是將一張圖片看成一個多維的list,例如對於一張圖片im,想要操作第四行第四列的畫素點就直接 im[3,3] 就可以獲取到這個點的RGB值。 第二種就是
【程式語言】利用CImage類對影象畫素的處理(影象二值化)
最近做的課程作業需要用到CImage函式處理影象,其中涉及到讀取影象以及對影象畫素進行操作,在這裡記錄一下自己的理解。 首先是CImage類的定義和讀取圖片 CImage srcImage; CImage dstImage; CString path = "
【影象處理】影象畫素隨機化:雪花漫天飛
近來經常和心理系做實驗,總是有各種“什麼什麼隨機化,刺激的物理性質保持一樣。。”的需求。之前做《去掩蔽》的實驗時,有一套圖片就是做的畫素隨機化,這是最簡單的隨機化了。當時影象只有兩種畫素,灰的和深灰的,而且深灰的比較少。於是我就統計了深灰畫素點的個數,然後在一張同樣大的灰色圖
Python 影象處理 OpenCV (2):畫素處理與 Numpy 操作以及 Matplotlib 顯示影象
![](https://cdn.geekdigging.com/opencv/opencv_header.png) 前文傳送門: [「Python 影象處理 OpenCV (1):入門」](https://www.geekdigging.com/2020/05/17/5513454552/) ## 普通
影象畫素點讀取和賦值
//取IplImage影象畫素值 int main() { IplImage* src = cvLoad("filename",0); //-1預設讀取原通道,0 灰度圖,1彩色圖 if(src!=0) &nb
OpenCV學習筆記(三)之影象畫素的提取
提取影象的畫素及畫素索引 Mat src, dst; src = imread("mountainandwater.jpg"); //讀取影象 if (src.empty()) { qDebug()<<"can
【電腦科學】【2017.11】【含原始碼】用於超光譜影象畫素分類的深度學習研究
本文為荷蘭代爾夫特理工大學(作者:I.A.F. Snuverink)的碩士論文,共128頁。 在超光譜(HS)成像中,每一個畫素都要捕獲波長光譜,這些光譜代表材料性質,即光譜特徵。因此,HS影象的分類是基於材料屬性的。本文介紹了一種在不同環境條件下的固定場景中進行HS影象畫素分類的
訪問影象畫素幾種方法
#include <iostream> #include <opencv2/opencv.hpp> #include <Windows.h> #include <opencv2/highgui/highgui.hpp> using namespace
opencv讀取影象畫素值讀取並儲存到txt檔案(二)灰度圖
#include "stdafx.h" #include"cv.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include <fstream> #include &l
opencv讀取影象畫素值讀取並儲存到txt檔案(一)RGB
#include “stdafx.h” #include"cv.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include #include #include “iost
sklearn:影象畫素與平行隨機森林的重要性
此示例顯示了使用來評估影象分類任務(面)中畫素的重要性。 畫素越熱,越重要。下面的程式碼還說明了如何在多個任務中並行化預測的構造和計算。 print(__doc__) from time import time import matplotlib.pyplot as plt from s
openCV--訪問影象畫素的三個方法
方法一 指標訪問:C操作符[ ] 方法二 迭代器iterater 方法三 動態地址計算 訪問速度上,debug模式下 ,方法一 > 方法二 > 方法
OpenCV二值化影象畫素操作
二值化影象畫素不是0就是255,資料型別為uchar。所以訪問方法是: // 這裡inputmat是二值化影象的mat inputmat.at<uchar>(y, x); 判斷是否為白色的方法: if (inputmat.at<uchar&g
遍歷影象畫素點的方法
一:椒鹽噪點的例子(隨機遍歷影象的某個畫素點) void salt(Mat &image,int n){ for(int k=0;k<n;k++){ //rand():隨機數產生函式 int i=rand()%image.cols; int j=r
OpenCV——修改影象畫素(隨心所欲)
這一節將講述OpenCV——修改影象畫素,根據自己需要新增特定的畫素部分 原圖如下,我們就是先在這個視訊流上新增一條直線段(有一定寬度的) 現在我們想新增一條,135行-455行,列350--360的直線段 #include<opencv2/opencv.hp
opencv中對影象畫素點訪問的三種方法利用程式進行解讀
程式碼放到自己的工程中,執行就可以的 #include <opencv2\opencv.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #includ