如何在画布上水平翻转图像?

时间:2017-03-30 18:27:26

标签: javascript html5 canvas webgl

在你抛弃我之前 - 我知道this answer,但它似乎对我不起作用。它的不同之处在于,我的图像数据源是WebGL画布 - 而不是img节点。

我正在尝试将ImageData放到画布上:

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画布,如下所示:

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()

2 个答案:

答案 0 :(得分:0)

使用负宽度进行翻译时适合我 index.html

node_modules/.bin/ng build --watch
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);
})();

答案 1 :(得分:0)

webGL画布可以像图像一样使用。您不需要使用慢gl.readPixelsctx.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);