>  기사  >  웹 프론트엔드  >  캔버스 이미지 처리

캔버스 이미지 처리

小云云
小云云원래의
2017-12-08 15:29:131869검색

Canvas는 JavaScript를 통해 2D 그래픽을 그립니다. 캔버스는 픽셀 단위로 렌더링됩니다. 캔버스에서는 그래픽이 그려지면 더 이상 브라우저의 관심을 끌 수 없습니다. 위치가 변경되면 그래픽으로 가려졌을 수 있는 개체를 포함하여 전체 장면을 다시 그려야 합니다.

canvas는 픽셀에 대한 기본 처리 작업을 구현합니다

// 픽셀 데이터 가져오기
var canvas = document.getElementById('CanvasElt');
var ctx = canvas.getContext('2d');
// 캔버스 가져오기 픽셀 정보 에서
//x는 복사가 시작되는 왼쪽 상단 모서리의 x 좌표입니다.
//y 복사를 시작할 왼쪽 상단의 y 좌표입니다.
//width 복사할 직사각형 영역의 너비입니다.
//heigh복사할 직사각형 영역의 높이입니다.
var canvasData = ctx.getImageData(x, y, canvas.width, canvas.height);
// 픽셀 정보 쓰기
ctx.putImageData(canvasData, 0, 0);
획득된 canvasData 객체에는 다음 멤버가 포함됩니다. 데이터 배열 구조는 대략 다음과 같습니다. 행별로 저장되고 열 지점이 하나의 열 지점에 저장됩니다. 각 지점은 RGBA인 4개의 첨자를 차지합니다. 여기서 y는 (아래쪽)입니다. 순방향), RGBA는 데이터[(ywidth+x)4], 데이터[(ywidth+x)4+1], 데이터[(ywidth+x)4+2], 데이터[(ywidth+x)4 +3입니다. ]. 픽셀을 얻을 수 있으면 이를 처리할 수 있습니다. 가장 간단한 방법은 그레이스케일 처리입니다. 그레이스케일 처리를 수행하는 가장 간단한 방법은 각 단계의 r, g 및 b를 추가하고 평균을 취하는 것입니다. , r, g, b에 각각 할당합니다.
//회색조 처리
함수 grey() {

var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
for(var i = 0; i < imageData.data.length; i += 4) {
var avg = (imageData.data[i] + imageData.data[i + 1] + imageData.data[i + 2]) / 3;
    imageData.data[i] = avg; // red
    imageData.data[i + 1] = avg; // green
    imageData.data[i + 2] = avg; // blue
    imageData.data[i + 3] = 255; //alpha
}
ctx1.putImageData(imageData, 0, 0);

}
픽셀 부정: 255는 해당 rgb 값을 뺀 다음 이를 원래 rgb에 할당합니다. 밝기 조정: 원래 rgb 값에 동일한 값을 무작위로 더하거나 뺍니다. 값 난수. 대비가 변경되거나 흐릿한 사진을 얻으려면 어떻게 해야 합니까? 컨볼루션 커널(Convolution Kernel) : 영상처리 분야에서 가장 일반적으로 사용되는 컨볼루션 커널은 소위 행렬의 컨볼루션(Convolution of the Matrix)으로, 아래 그림과 같이 빨간색 상자 안의 값을 계산할 때 먼저 주변 녹색 안의 8개 숫자를 추출합니다. 그런 다음 적용된 행렬의 해당 위치를 곱한 다음 제품을 더하여 최종 값을 얻습니다.

예: (40 x 0)+(42 x 1)+(46 x 0)+ (46 x 0)+(50 x 0)+(55 x 0)+ (52 x 0)+(56 x 0 )+(58 x 0)= 42 그러면 어떻게 흐릿한 사진을 얻을 수 있을까요? 이미지의 픽셀과 행렬 [1,1,1,1,1,1,1,1,1]을 사용하여 컨볼루션 커널을 찾습니다. 이때 픽셀은 255를 초과할 수 있으므로 기본 숫자로 나눕니다. 8개 중 사진은 흐림 필터가 적용된 사진입니다. 대비는 1입니다. 흰색 사진의 밝기를 높이세요. 2. 검은색을 더 어둡게 만들고 [0,0,0, 0,3,0,0 ,0,0] 컨볼루션 커널, 255를 초과한 다음 적절한 밑수 150을 뺄 수도 있습니다. 이제 컨볼루션 커널 함수가 필요합니다. 함수의 첫 번째 매개변수는 imageData 객체입니다. 두 번째 매개변수는 들어오는 행렬에 해당하는 배열입니다. 다음 행렬 a b c d e f g h i인 경우 전달된 두 번째 매개변수는 [a,b,c,d,e,f,g,h,i]여야 합니다. ] 세 번째 매개변수는 제수 인자입니다. 네 번째 매개변수는 오프셋입니다.
function ConvolutionMatrix(input, m, pisor, offset) {

var output =document.createElement("canvas").getContext('2d').createImageData(input);
var w = input.width,
    h = input.height;
var iD = input.data,
    oD = output.data;
for(var y = 1; y < h - 1; y += 1) {
    for(var x = 1; x < w - 1; x += 1) {
        for(var c = 0; c < 3; c += 1) {
            var i = (y * w + x) * 4 + c;
            // 卷积核计算
            oD[i] = offset +(m[0] * iD[i - w * 4 - 4] + m[1] * iD[i - w * 4] + m[2] * iD[i - w * 4 + 4] +m[3] * iD[i - 4] + m[4] * iD[i] + m[5] * iD[i + 4] +m[6] * iD[i + w * 4 - 4] + m[7] * iD[i + w * 4] + m[8] * iD[i + w * 4 + 4]) /pisor;
        }
                    oD[(y * w + x) * 4 + 3] = 255; // 设置透明度为不透明
    }
}
return output;

}
//흐림 처리
function mohu(){

var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
var m = [1,1,1,1,1,1,1,1,1];
var output = ConvolutionMatrix(imageData, m, 10,0);
ctx1.putImageData(output,0,0);

}

//대비 처리
function level(){

var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
var m = [0,0,0,0,3,0,0,0,0];
var output = ConvolutionMatrix(imageData, m, 1,-150);
ctx1.putImageData(output,0,0);

}

사진에도 원하는 데이터가 있을 수 있습니다

사진의 각 픽셀은 4개의 RGBA 요소로 구성되어 있기 때문에 단순히 사진에 대해 getImageData를 사용하여 분석할 수 있는 것은 알 필요가 없는 많은 데이터일 뿐이므로, 특정 색상값을 자체 데이터로 볼 수 있나요?
예: 사진에서 흰색 픽셀(r:255,g:255:b:255,a:255)을 찾고 싶습니다. getImageData를 통해 사진의 데이터를 가져오고 각 픽셀의 데이터를 검색할 수 있습니다. 해당 rgba인가요? 추출한 다음 사진의 너비와 높이에 따라 각 흰색 픽셀의 위치 정보를 계산할 수 있습니다.
캔버스 이미지 처리

그림도 더 잘 통과해야 합니다

이전 단계에서 우리는 이미 그림의 특정 요소에 대한 관련 위치 정보를 얻는 작업을 알고 있지만 그림이 매우 일반적인 그림인 경우 다음이 필요합니다. 그것을 순회하려면 imageData의 각 정보에 대해 순회를 줄이는 더 좋은 방법이 있습니까?
정답은: 사진의 기본 색상은 검정색(r:0,g:0,b:0,a:0)이지만, 반드시 정답이 하나만 있는 것은 아닙니다. 다른 좋은 방법도 있을 수 있지만 원칙은 다음과 같습니다. 와 동일해야 합니다.
각 픽셀의 r을 순회하여 r!=0이면 이 픽셀의 나머지 g, b, a를 순회합니다. 이 단계는 이전 단계보다 더 쓸모가 없다는 것입니다. 검은색을 사용하는 것이 더 좋습니다. 검은색은 모두 0인 상태이고 계산하기 쉽기 때문입니다.
캔버스 이미지 처리

더 나은 최적화가 있나요?

위의 두 단계 외에도 사용된 이미지가 너무 커서 더 많은 순회가 발생하며, 최종 데이터가 원하는 크기라면 데이터 추출에만 관심이 있습니다. 원본 이미지의 크기를 여러 번 확장할 수 있으며, 새 이미지를 사용하여 얻은 데이터에 최종적으로 해당 배수를 곱한 결과가 우리가 원하는 데이터입니다.

캔버스 이미지 처리

관련 권장 사항:

캔버스로 사진을 처리하는 방법

캔버스를 사용하여 공과 마우스 사이의 상호 작용을 구현하는 방법

JavaScript+html5 캔버스 사용 예 사진에 하이퍼링크 그리기 코드

위 내용은 캔버스 이미지 처리의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.