0

Before you throw me out - I am aware of this answer, but it does not seem to work for me. It is also different in that the source of the image data in my case is a WebGL canvas - not an img node.

I am trying to put ImageData onto a canvas like so:

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

and then to flip it like so:

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

but this fails miserably.

The data comes from a WebGL canvas like this:

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

so I've considered low-level operations on the pixel array as a solution, but before I get into that I thought I'd ask.

I have a hunch that drawImage is insensitive to transforms, but that would be funny. Please please don't make me use toDataURL()

Community
  • 1
  • 1
simone
  • 4,667
  • 4
  • 25
  • 47
  • *"fails miserably"* means what exactly? – LJᛃ Mar 30 '17 at 19:59
  • Sorry @LJᛃ - frustration seeped through. It doesn't do anything. It still results in a picture, but no flipping. – simone Mar 30 '17 at 20:07
  • Possible duplicate of [How can I flip the result of WebGLRenderingContext.readPixels()?](http://stackoverflow.com/questions/41969562/how-can-i-flip-the-result-of-webglrenderingcontext-readpixels) – Kaiido Mar 30 '17 at 23:31

2 Answers2

0

Works for me when translating using the negative width 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>
LJᛃ
  • 7,655
  • 2
  • 24
  • 35
0

The webGL canvas can be used just like an image. You don't need to use the slow gl.readPixels and ctx.setImageData methods to move the image data

// 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);
Blindman67
  • 51,134
  • 11
  • 73
  • 136