如何水平翻转 canvas 上已有的图像?
How to horizontally flip images already on the canvas?
在你把我赶出去之前 - 我 知道 this answer,但它似乎对我不起作用。它的不同之处还在于,在我的例子中,图像数据的来源是 WebGL canvas - 而不是 img 节点。
我正在尝试将 ImageData 放到 canvas 上,如下所示:
var c = document.createElement('canvas');
c.setAttribute('width', size.width);
c.setAttribute('height', size.height);
$('body').append(c)
// p contains a Uint8ClampedArray with imagedata coming from a WebGL canvas
var i = new ImageData(p, size.width, size.height);
var ctx = c.getContext('2d');
ctx.putImageData(i, 0, 0);
然后像这样翻转它:
var d = document.createElement('canvas');
d.width = c.width; d.height = c.height;
d.getContext('2d').drawImage(c, 0, 0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.scale(-1, 1);
ctx.translate(c.width, 0);
ctx.drawImage(d, 0, 0);
但这惨遭失败。
数据来自 WebGL canvas,如下所示:
var gl = renderer.domElement.getContext("webgl")
var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
所以我考虑过对像素阵列进行低级操作作为一种解决方案,但在开始之前我想我会问一下。
我有一种预感,drawImage 对变换不敏感,但这很有趣。请不要让我使用 toDataURL()
在使用负宽度进行翻译时对我有用
ctx.translate(-c.width, 0);
var webglReadPixelsData;
// draw some webgl
(function(){
var
ctx=webgl.getContext('webgl',{preserveDrawingBuffer:true}),
p=ctx.createProgram(),
vs=ctx.createShader(ctx.VERTEX_SHADER),
fs=ctx.createShader(ctx.FRAGMENT_SHADER),
vb=ctx.createBuffer()
;
ctx.shaderSource(vs,"attribute vec2 p;void main(){gl_Position=vec4(p*2.-1.,0,1);}");
ctx.compileShader(vs);
ctx.shaderSource(fs,"void main(){gl_FragColor=vec4(sin(gl_FragCoord.x*.2+gl_FragCoord.y*.2),0,0,1);}");
ctx.compileShader(fs);
ctx.attachShader(p,vs);
ctx.attachShader(p,fs);
ctx.linkProgram(p);
ctx.useProgram(p);
ctx.bindBuffer(ctx.ARRAY_BUFFER,vb);
ctx.bufferData(ctx.ARRAY_BUFFER,new Float32Array([0,0,1,0,1,1,0,1]),ctx.STATIC_DRAW);
ctx.enableVertexAttribArray(0);
ctx.vertexAttribPointer(0,2,ctx.FLOAT,false,0,0);
ctx.viewport(0,0,ctx.canvas.clientWidth,ctx.canvas.clientHeight);
ctx.drawArrays(ctx.TRIANGLE_FAN,0,4);
webglReadPixelsData = new Uint8Array(ctx.drawingBufferWidth * ctx.drawingBufferHeight * 4);
ctx.readPixels(0, 0, ctx.drawingBufferWidth,ctx.drawingBufferHeight, ctx.RGBA, ctx.UNSIGNED_BYTE, webglReadPixelsData);
})();
// Flip image data
(function(){
var ctx=canvas2d.getContext('2d');
var id=new ImageData(webgl.clientWidth, webgl.clientHeight);
id.data.set(webglReadPixelsData);
ctx.putImageData(id,0,0);
var d = intermediate;
d.getContext('2d').drawImage(canvas2d, 0, 0);
ctx.clearRect(0,0,ctx.canvas.clientWidth,ctx.canvas.clientHeight);
ctx.scale(-1, 1);
ctx.translate(-ctx.canvas.clientWidth, 0);
ctx.drawImage(d, 0, 0);
})();
#webgl {display:block;outline:1px solid #f00;}
#canvas2d{display:block;outline:1px solid #0f0;}
#intermediate{outline:1px solid #00f;}
<h1>WebGL Canvas</h1>
<canvas id="webgl"></canvas>
<h1>Intermediate Canvas</h1>
<canvas id="intermediate"></canvas>
<h1>2D Canvas</h1>
<canvas id="canvas2d"></canvas>
webGL canvas 可以像图像一样使用。您不需要使用缓慢的 gl.readPixels
和 ctx.setImageData
方法来移动图像数据
// where canvasGL is the webGL canvas and ctx is the 2D canvas context
ctx.setTransform(1,0,0,-1,0,canvasGL.height);
ctx.drawImage(canvasGL,0,0);
在你把我赶出去之前 - 我 知道 this answer,但它似乎对我不起作用。它的不同之处还在于,在我的例子中,图像数据的来源是 WebGL canvas - 而不是 img 节点。
我正在尝试将 ImageData 放到 canvas 上,如下所示:
var c = document.createElement('canvas');
c.setAttribute('width', size.width);
c.setAttribute('height', size.height);
$('body').append(c)
// p contains a Uint8ClampedArray with imagedata coming from a WebGL canvas
var i = new ImageData(p, size.width, size.height);
var ctx = c.getContext('2d');
ctx.putImageData(i, 0, 0);
然后像这样翻转它:
var d = document.createElement('canvas');
d.width = c.width; d.height = c.height;
d.getContext('2d').drawImage(c, 0, 0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.scale(-1, 1);
ctx.translate(c.width, 0);
ctx.drawImage(d, 0, 0);
但这惨遭失败。
数据来自 WebGL canvas,如下所示:
var gl = renderer.domElement.getContext("webgl")
var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
所以我考虑过对像素阵列进行低级操作作为一种解决方案,但在开始之前我想我会问一下。
我有一种预感,drawImage 对变换不敏感,但这很有趣。请不要让我使用 toDataURL()
在使用负宽度进行翻译时对我有用
ctx.translate(-c.width, 0);
var webglReadPixelsData;
// draw some webgl
(function(){
var
ctx=webgl.getContext('webgl',{preserveDrawingBuffer:true}),
p=ctx.createProgram(),
vs=ctx.createShader(ctx.VERTEX_SHADER),
fs=ctx.createShader(ctx.FRAGMENT_SHADER),
vb=ctx.createBuffer()
;
ctx.shaderSource(vs,"attribute vec2 p;void main(){gl_Position=vec4(p*2.-1.,0,1);}");
ctx.compileShader(vs);
ctx.shaderSource(fs,"void main(){gl_FragColor=vec4(sin(gl_FragCoord.x*.2+gl_FragCoord.y*.2),0,0,1);}");
ctx.compileShader(fs);
ctx.attachShader(p,vs);
ctx.attachShader(p,fs);
ctx.linkProgram(p);
ctx.useProgram(p);
ctx.bindBuffer(ctx.ARRAY_BUFFER,vb);
ctx.bufferData(ctx.ARRAY_BUFFER,new Float32Array([0,0,1,0,1,1,0,1]),ctx.STATIC_DRAW);
ctx.enableVertexAttribArray(0);
ctx.vertexAttribPointer(0,2,ctx.FLOAT,false,0,0);
ctx.viewport(0,0,ctx.canvas.clientWidth,ctx.canvas.clientHeight);
ctx.drawArrays(ctx.TRIANGLE_FAN,0,4);
webglReadPixelsData = new Uint8Array(ctx.drawingBufferWidth * ctx.drawingBufferHeight * 4);
ctx.readPixels(0, 0, ctx.drawingBufferWidth,ctx.drawingBufferHeight, ctx.RGBA, ctx.UNSIGNED_BYTE, webglReadPixelsData);
})();
// Flip image data
(function(){
var ctx=canvas2d.getContext('2d');
var id=new ImageData(webgl.clientWidth, webgl.clientHeight);
id.data.set(webglReadPixelsData);
ctx.putImageData(id,0,0);
var d = intermediate;
d.getContext('2d').drawImage(canvas2d, 0, 0);
ctx.clearRect(0,0,ctx.canvas.clientWidth,ctx.canvas.clientHeight);
ctx.scale(-1, 1);
ctx.translate(-ctx.canvas.clientWidth, 0);
ctx.drawImage(d, 0, 0);
})();
#webgl {display:block;outline:1px solid #f00;}
#canvas2d{display:block;outline:1px solid #0f0;}
#intermediate{outline:1px solid #00f;}
<h1>WebGL Canvas</h1>
<canvas id="webgl"></canvas>
<h1>Intermediate Canvas</h1>
<canvas id="intermediate"></canvas>
<h1>2D Canvas</h1>
<canvas id="canvas2d"></canvas>
webGL canvas 可以像图像一样使用。您不需要使用缓慢的 gl.readPixels
和 ctx.setImageData
方法来移动图像数据
// where canvasGL is the webGL canvas and ctx is the 2D canvas context
ctx.setTransform(1,0,0,-1,0,canvasGL.height);
ctx.drawImage(canvasGL,0,0);