Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

putImageData is not drawing anything in the canvas #180

Open
QuevedoIB opened this issue Apr 23, 2020 · 7 comments
Open

putImageData is not drawing anything in the canvas #180

QuevedoIB opened this issue Apr 23, 2020 · 7 comments
Labels

Comments

@QuevedoIB
Copy link

QuevedoIB commented Apr 23, 2020

canvasContext.putImageData(data,0,0) not drawing anything

I'm trying to pass an ImageData element to the canvas so it's displayed on it, my code looks like:

import Canvas, {ImageData} from 'react-native-canvas';

...

const handleCanvas = async canvas => {
    canvas.width = sizes.width;
    canvas.height = sizes.height;
    const ctx = canvas.getContext('2d');

    const data = await ctx.createImageData(
      encodedImage.width,
      encodedImage.height,
      encodedImage.data,
    );

    console.log(
      'data',
      data,
      data instanceof ImageData,
      'encoded',
      encodedImage,
      encodedImage instanceof ImageData,
    );

    await ctx.putImageData(data, 0, 0);
  };

...

{encodedImage && (
            <Canvas
              ref={handleCanvas}
              style={{borderWidth: 1, borderColor: 'red', zIndex: 1000000}}
            />
)}

Outputs:

Screenshot 2020-04-23 at 12 09 49

encodedImage is a black and white ImageData mask from https://www.npmjs.com/package/@tensorflow-models/body-pix#returns-4

Canvas is that red box:

Screenshot 2020-04-23 at 12 27 56

Nothing is painted inside when using putImageData with Outputs data.

If I try to pass the ImageData to another canvas context I get the following error: Error: Argument 1('imagedata') to CanvasRenderingContext2D.putImageData must be an instance of ImageData

@iddan
Copy link
Owner

iddan commented Apr 23, 2020

createImageData() is not supported currently (though it should be pretty easy to implement PRs are welcome). Can you try using new ImageData(...) instead?

@iddan iddan added the bug label Apr 23, 2020
@QuevedoIB
Copy link
Author

Reason I'm not using new ImageData(...) is that it gives me error:

Screenshot 2020-04-23 at 12 36 17

Screenshot 2020-04-23 at 12 37 47

This error is related to https://stackoverflow.com/questions/38556730/imagedata-byte-length-is-not-a-multiple-of-4-width which says length of Uint8ClampedArray needs to be the multiple of width, height and 4. In my image case 612480 / (480 * 319 * 4) = 1 so it's fine but it still gives me the error. @iddan

@QuevedoIB
Copy link
Author

Anyways my expectation is that given the following input:

Screenshot 2020-04-23 at 13 00 05

(An ImageData given from another source)

putImageData should work as expected but it gives the following error:

Screenshot 2020-04-23 at 13 03 33

Because it's not an initialized ImageData from new ImageData/createImageData.

 const handleCanvas = async canvas => {
    canvas.width = sizes.width;
    canvas.height = sizes.height;
    const ctx = canvas.getContext('2d');

    console.log('encoded', encodedImage, encodedImage instanceof ImageData);

    await ctx.putImageData(encodedImage, 0, 0);
  };

@QuevedoIB
Copy link
Author

My workaround is to initialize with new ImageData(...) and then add the properties to the instance.

 const handleCanvas = async canvas => {
    canvas.width = sizes.width;
    canvas.height = sizes.height;
    const ctx = canvas.getContext('2d');

    const data = new ImageData(canvas);

    data.data = encodedImage.data;
    data.width = encodedImage.width;
    data.height = encodedImage.height;

    console.log(data, data instanceof ImageData);

    await ctx.putImageData(data, 0, 0);
  };

Screenshot 2020-04-23 at 14 15 56

That way I get the desired ImageData instance with the proper data, but putImageData still does nothing to the canvas. (Nothing is drawn) Did someone get putImageData working before?

Screenshot 2020-04-23 at 14 17 18

@bbhopesh
Copy link

I am also facing bug with putDataImage. When I run example app without any changes, it renders differently on different platforms. Check top left rectangle in two images below, one is from an emulator and one is from real phone. However, both are rendering wrong. If code was behaving correctly, entire top left rectangle would have been black.
image

image

@esbenvb
Copy link

esbenvb commented Jul 27, 2023

I think I made something work. I have one canvas drawCanvas where I can draw with free hand, and another canvas canvas2 where I want to put the data I have drawn.

Acoording to my research, the important thing is that the ImageData you draw on a canvas has a reference to that canvas.

      const drawingData = await drawCanvas
        .getContext('2d')
        .getImageData(0, 0, drawCanvas.width, drawCanvas.height);

      const data = Object.values(drawingData.data);
      const newImageData = new ImageData(
        canvas2,
        data,
        drawCanvas.width,
        drawCanvas.height,
      );
      context2.putImageData(newImageData, 0, 0);

@songjingwei
Copy link

I think I made something work. I have one canvas drawCanvas where I can draw with free hand, and another canvas canvas2 where I want to put the data I have drawn.

Acoording to my research, the important thing is that the ImageData you draw on a canvas has a reference to that canvas.

      const drawingData = await drawCanvas
        .getContext('2d')
        .getImageData(0, 0, drawCanvas.width, drawCanvas.height);

      const data = Object.values(drawingData.data);
      const newImageData = new ImageData(
        canvas2,
        data,
        drawCanvas.width,
        drawCanvas.height,
      );
      context2.putImageData(newImageData, 0, 0);

Thank You, Sir. This way solve my problem!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants