getImagedata / putImagedata와 함께 캔버스와 같은 HTML 이미지를 사용할 수 있습니까?
-
22-07-2019 - |
문제
HTML5 캔버스 요소 인 것처럼 HTML 이미지에 포함 된 데이터를 동적으로 수정/액세스하는 방법이 있는지 알고 싶습니다. 캔버스를 사용하면 javaScript에서 getImagedata () 및 putImagedata ()를 사용하여 원시 픽셀 데이터에 액세스 할 수 있지만 지금까지 이미지 로이 작업을 수행하는 방법을 알 수 없었습니다.
해결책
// 1) Create a canvas, either on the page or simply in code
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 2) Copy your image data into the canvas
var myImgElement = document.getElementById('foo');
ctx.drawImage( myImgElement, 0, 0 );
// 3) Read your image data
var w = myImgElement.width, h=myImgElement.height;
var imgdata = ctx.getImageData(0,0,w,h);
var rgba = imgdata.data;
// 4) Read or manipulate the rgba as you wish
for (var px=0,ct=w*h*4;px<ct;px+=4){
var r = rgba[px ];
var g = rgba[px+1];
var b = rgba[px+2];
var a = rgba[px+3];
}
// 5) Update the context with newly-modified data
ctx.putImageData(imgdata,0,0);
// 6) Draw the image data elsewhere, if you wish
someOtherContext.drawImage( ctx.canvas, 0, 0 );
2 단계는 페이지가 아닌 스크립트에 직접로드 된 이미지에서 가져올 수도 있습니다.
// 2b) Load an image from which to get data
var img = new Image;
img.onload = function(){
ctx.drawImage( img, 0, 0 );
// ...and then steps 3 and on
};
img.src = "/images/foo.png"; // set this *after* onload
다른 팁
이미지를 캔버스 요소로 그릴 수 있습니다. DrawImage (), 그런 다음 캔버스에서 픽셀 데이터를 가져옵니다.
이 코드에 문제가있는 후에는 Phrogz의 답변에 하나 또는 두 가지를 추가하고 싶습니다.
// 1) Create a canvas, either on the page or simply in code
var w = myImgElement.width, h=myImgElement.height; // NEw : you need to set the canvas size if you don't want bug with images that makes more than 300*150
var canvas = document.createElement('canvas');
canvas.height = h;
canvas.width = w;
var ctx = canvas.getContext('2d');
// 2) Copy your image data into the canvas
var myImgElement = document.getElementById('foo');
ctx.drawImage( myImgElement, 0, 0, w, h ); // Just in case...
// 3) Read your image data
var imgdata = ctx.getImageData(0,0,w,h);
var rgba = imgdata.data;
// And then continue as in the other code !
그것은 저를 위해 일했습니다 (IE10X64, Win7의 Chromex64, Chromium Arm Linux ... ... Firefox 20 Arm Linux와 함께 버그가있는 것 같습니다 ... 확실하지 않습니다 ... 다시 테스트).
-HTML--
<canvas id="myCanvas" width="600" height="300"></canvas>
<canvas id="myCanvasOffscreen" width="1" height="1"></canvas>
-JS-
// width & height can be used to scale image !!!
function getImageAsImageData(url, width, height, callack) {
var canvas = document.getElementById('myCanvasOffscreen');
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0, width, height);
imgData = context.getImageData(0,0,width, height);
canvas.width = 1;
canvas.height = 1;
callack( imgData );
};
imageObj.src = url;
}
-- 그 다음에 --
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var imgData;
getImageAsImageData('central_closed.png', IMG_WIDTH, IMG_HEIGHT,
function(imgData) {
// do what you want with imgData.data (rgba array)
// ex. colorize( imgData, 25, 70, 0);
ctx.putImageData(imgData,0,0);
}
);
먼저 캔버스에 그림을 그린 다음 캔버스에서 Imagedata를 얻고 싶어합니다. JS는 "크로스 도메인 액세스"라고 생각하기 때문에 잘못된 방법입니다. -도메인 액세스 "이미지에 대한 도메인 액세스. 당신은 루트 장소에 넣고"localhost "로 액세스하여 시도해 볼 수 있습니다.
가능한지 확실하지 않지만 PHP에서 픽셀 정보를 요청할 수 있습니다. GD 라이브러리가 쉬운 작업이지만 반드시 느려질 것입니다. 응용 프로그램을 지정하지 않았으므로 이미지를 쿼리하거나 수정할 수있는 것보다 벡터 이미지가 될 수있는 경우이 작업에 대한 SVG를 확인하는 것이 좋습니다.
직접 작업합니다 IMG 요소 또한 유효합니다 :
var image = document.createElement('img'),w,h ;
image.src = "img/test.jpg" ;
$(image).one('load',function(){
w = image.naturalWidth ;
h = image.naturalHeight ;
var cnv = document.createElement('canvas') ;
$(cnv).attr("width",w) ;
$(cnv).attr("height",h) ;
var ctx = cnv.getContext('2d') ;
ctx.drawImage(image,0,0) ;
var imgdata = ctx.getImageData(0,0,w,h) ;
var rgba = imgdata.data ;
for (var px=0,ct=w*h*4;px<ct;px+=4){
var r = rgba[px+0] ;
var g = rgba[px+1] ;
var b = rgba[px+2] ;
var a = rgba[px+3] ;
// Do something
rgba[px+0] = r ;
rgba[px+1] = g ;
rgba[px+2] = b ;
rgba[px+3] = a ;
}
ctx.putImageData(imgdata,0,0) ;
$("body").append(cnv) ;
}) ;