前端提高篇(六十九):HTML進階10:canvas畫布基本知識(四)繪製影象、模糊問題

2021-03-23 12:01:00

在這裡插入圖片描述

drawImage匯入圖片

var img = new Image();
img.src = './img/3.jpg';//建立圖片
img.onload = function(){
    ctx.drawImage(img,100,100);//當圖片載入完成,再畫圖
}

在這裡插入圖片描述
剪下:
將原圖(sx,sy,sw,sh)位置裁切下來,放在畫布的(x,y,w,h)位置上

var img = new Image();
img.src = './img/13.png';
img.onload = function(){
    ctx.drawImage(img,300,150,100,100,200,200,50,50);
}

在原圖的(300,150)處剪裁下寬100高100的矩形,放在畫布(200,200)的位置,並縮成(50,50)
在這裡插入圖片描述

原圖是這樣的:
在這裡插入圖片描述

getImageData()

getImageData() 方法返回 ImageData 物件,該物件拷貝了畫布指定矩形的畫素資料。

對於 ImageData 物件中的每個畫素,都存在著四方面的資訊,即 RGBA 值:

img.onload = function(){
    ctx.drawImage(img,0,0,400,400);
    ctx.getImageData(img, 0,0,400,400);//獲取所有的畫素資訊
}

這個需要將圖片放到伺服器上再操作,本地地址不能識別(file://…)

putImageData()

通過 putImageData() 將影象資料放到畫布

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 50, 50);
copy();//將上面繪製的圖形的畫素資料複製一下,挪到另一個位置
function copy() {
    var imgData = ctx.getImageData(10, 10, 50, 50);
    ctx.putImageData(imgData, 10, 70);
}

在這裡插入圖片描述
反像處理:

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 50, 50);

reverse();//將每一個畫素取反

function reverse() {
    var imgData = ctx.getImageData(10, 10, 50, 50);
    for (var i = 0; i < imgData.data.length; i +=4){
        imgData.data[i] = 255 - imgData.data[i];
        imgData.data[i+1] = 255 - imgData.data[i+1];
        imgData.data[i+2] = 255 - imgData.data[i+2];
    }
    ctx.putImageData(imgData, 10, 70);
}

在這裡插入圖片描述

抽取canvas為一張圖片

將已經獲取到的畫素資料轉成base64格式,建立一張新img,將新img的src改成剛剛得到的base64編碼即可

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 50, 50);
// copy();
var imgData = reverse();
var baseSrc = myCanvas.toDataURL();//得到base64編碼
console.log(baseSrc);//輸出base64編碼
var newImg = new Image();
newImg.src = baseSrc;//建立新圖片,將畫素資料的base64編碼傳入
document.body.appendChild(newImg);//將圖片插入dom中

function reverse() {
    var imgData = ctx.getImageData(10, 10, 50, 50);
    for (var i = 0; i < imgData.data.length; i +=4){
        imgData.data[i] = 255 - imgData.data[i];
        imgData.data[i+1] = 255 - imgData.data[i+1];
        imgData.data[i+2] = 255 - imgData.data[i+2];
    }
    
    ctx.putImageData(imgData, 10, 70);
    return imgData;//將畫素資料返回
    
}

模糊問題

1.點陣圖畫素放大會失真,canvas為點陣圖畫素(向量圖放大不失真)
2.canvas繪圖時,會從兩個物理畫素的中間位置開始繪製並向兩邊擴散0.5個物理畫素。由於不存在0.5個畫素,兩邊都取了1畫素,視覺上就造成了模糊

在這裡插入圖片描述

相當於,2個畫素當成了1個畫素來處理

解決方案:放大再縮小展示
canvas的width/height屬性寫w/h;css樣式寫1/2就好
也就是一開始說的,我把width/height屬性設定成400,css樣式裡的寬高設定成200px,canvas中每個單位相當於是0.5px,畫起來更精細,解決了模糊問題

css樣式是200px * 200px,但是canvas定400*400,抽取出來的圖片依然是400px * 400px的

在這裡插入圖片描述