1

I'm new to Three.js, and to graphics generally, and I have been looking for a way to find the topmost and bottommost visible points in a PNG with a transparent background. I know in a vague sense that much of graphics manipulation is done by understanding the image as an array of pixels, so I picture this to essentially be iterating through the array for non-transparent pixels with the largest and smallest y-axis values. What feature in Three.js - or perhaps straight Javascript - will give me access to this data (this array?), or is there an even more direct way to achieve my goal already built into the library?

My goal is to vertically center the image according to its visible contents.

Thanks!

- UPDATE -

Taking a leaf from @Paul Green, I did a search for Three.js content related to getImageData (a function used to get a pixel array from a canvas context), hoping there was some equivalent function in Three.js. I'm looking for something that stays out of the canvas and in the Three.js (webGL) realm as I'm not using the canvas in my script. I'm also looking for something that can get the info before the image is rendered. So far, a Three.js dataTexture looks related but I still don't exactly understand it or how to use it. Any guidance would be appreciated!

gromiczek
  • 2,970
  • 5
  • 28
  • 49
  • what do you mean by "topmost and bottommost visible points"? The most and least transparent pixel? – timonsku Mar 19 '14 at 17:47
  • @ Paul Green - Ah, good question. I mean the coordinates of the top and bottom of the image in the transparent background: As an example, if my transparent PNG has a picture of a tree on it, I want to know the y-coordinates at the top and bottom of the tree. Is that clearer? – gromiczek Mar 19 '14 at 17:54

1 Answers1

1

You can get the pixels from an image using the method described in this question: How to use JavaScript or jQuery to read a pixel of an image when user clicks it?

var img = new Image();
img.src = 'image.jpg';
var context = document.getElementById('canvas').getContext('2d');
context.drawImage(img, 0, 0);
data = context.getImageData(x, y, 1, 1).data;

Then loop through the array of pixels and check for the threshold value you are looking for. 0 being fully transparent and 255 being fully opaque.

This question might be a help aswell on how to access the specific color channel: getPixel from HTML Canvas?

You will want to look at pix[i+3] which in the linked example holds the alpha channel.

Your current pixel position is simply calculated by using the current loop iteration and dividing it by your width which gives you the current height.

For example your image is 200x50 px. You hit a not fully transparent pixel at loop iteration 534, 534/200 = 2 so your are 2 pixels down at the Y axis and then get the remainder with 534 mod 200. So you know how far "in" your at the X axis.

Community
  • 1
  • 1
timonsku
  • 1,249
  • 2
  • 21
  • 45
  • Is there any way of doing this without drawing the image to a canvas? I'm not using a canvas (a div container instead), and I am hoping to compute the size before adding it into a Three.js Object3D and then adding that to the scene. Ideas? Thanks. – gromiczek Mar 19 '14 at 18:18
  • No there is no other way to get the pixels from an image in JS. E: Well it might be possible with some trickery with Base64 encoded images but none that I know of. http://en.wikipedia.org/wiki/Base64 – timonsku Mar 19 '14 at 18:20
  • Thanks for the tip. I took a your function suggestions and did further searching - added an update above. – gromiczek Mar 19 '14 at 19:17
  • 1
    I did end up using `getImageData()` as you recommended, eventually substituting `canvas = document.createElement("canvas"); context = canvas.getContext("2d");` for the `document.getElementById('canvas')` in your code above. I skipped rendering the canvas to the browser by omitting the `onload="addElement()"` in the `` tag. I had no idea one could use all the `canvas` tools without rendering the canvas to the browser! – gromiczek Mar 21 '14 at 15:17
  • 1
    Forgot about your updated question but seems you found the solution yourself. The best way to learn anyway. The canvas feature offers a lot of easy to use possibilities to process images in your browser as an alternative to the way more complex WebGL shaders. – timonsku Mar 22 '14 at 14:58