#2612 gfx: setPixel and getPixel

Kevin Tue 20 Jun

Are there no direct methods for these?

image.setPixel(x, y, color) color = image.getPixel(x,y)

I need to create an image buffer and draw each pixel individually, as well as read neighboring pixels. That will all get sent out as a PNG in the end.

brian Tue 20 Jun

You can have a new graphics context to draw to a buffered image, and then use drawLine.

SlimerDude Tue 20 Jun

I've wanted these methods many a time too!

From previous investigations, if I remember correctly, there's no reason why gfx.setPixel(x, y) can't be implemented (as long as the brush is just a simple a Colour and not a pen stroke or anything).

It's on my TODO list to submit a patch for this. For now, as Brian said, I just use gfx.drawLine() with the start and end coors set to the same coors.

As for gfx.getPixel() - that would be great (as would being able to create a transparent image!) but the underlying eclipse SWT doesn't make it easy. If you can find any documentation on it, I'll try to look into it again.

Kevin Tue 20 Jun

Is there any way to directly access the image buffer as a 2d array? Without being able to read a pixel, I will be forced to use ... gulp! ... Java. Their image classes are very scary. :(

Also, isn't using a 1-pixel line horribly, horribly inefficient rather than just terribly inefficient? I considered it before discarding the thought. I'm already going to be running some heavy maths.

I suppose I could add these methods, but I'm not sure I currently have skillz mad enough to do it yet. I'm assuming just a wrapper around the Java methods would be needed, although I haven't fully explored them yet. Just getting a mutable image buffer made me cry.

SlimerDude Tue 20 Jun

Hi Kevin,

Is there any way to directly access the image buffer as a 2d array?

Sadly, no. For now, if you're creating / drawing your own images, you could try create your own image buf at the same time.

It looks like a getPixel() may be possible in Java after all. Here are some links, mainly for myself for when I get round to looking at it:

isn't using a 1-pixel line horribly, horribly inefficient rather than just terribly inefficient?

Maybe, or maybe the underlying gfx lib is smart enough to notice the 2 coors are the same? Dunno, I've not profiled it. Anyway, right now, there's no other way!

brian Tue 20 Jun

Maybe some confusion, but the gfx::Image API is not an API to work with low-level image data, color space, etc. It provides access to the underlying rendering framework for drawing to a buffered image to render to the screen or to encode to a file. As such drawLine with one pixel is going to have no noticeable performance difference if there was a drawPixel (which isn't exposed by most rendering APIs anyhow). I think maybe the core problem is you need to use a different sort of image library - accessing individual pixels is different then a rendering pipeline for shapes, fonts, alpha compositing, etc

Kevin Tue 20 Jun

One last question before I give up: Can I create my own 2d array of pixels (i.e. rgba structs) to work on and then ship it off somewhere to be turned into a PNG?

The format is simple enough to write out as a byte stream, but I was hoping to enjoy some baked in goodness.

SlimerDude Tue 20 Jun

rendering framework for drawing to a buffered image

Given buffered images are inherently RGB raster images, it is not unreasonable to expect to get and set RGB pixels. No one is asking for a low level colour space API, just a couple of higher level convenience methods - something that Fantom often excels at.

The coordinate system is already working at the pixel level, so I see no harm in having a Graphics.drawPixel(x, y).

Can I create my own 2d array of pixels ... turned into a PNG?

Tricky. You'd have to create an SWT Image, then set pixels from its getImageData() to create your image.

Then see the last comment in the forum post: gfx::Image Creation from IntArray for code on converting an SWT image to an FWT image.

Kevin Tue 20 Jun

Haha! Thanks, but that's the sort of Java-esque gymnastics I'm trying to avoid. Maybe I can use JavaScript since it has an ImageData object that is stored in a flat array (image[0] = pixel1.r, image[1] = pixel1.g, etc.)

Anyway, all this groovy stuff is found in org.eclipse.swt.graphics.ImageData, but I can think of no reason why to have a separate class to do the pixel-level operations from the more comprehensive drawing ops. ¯\_(ツ)_/¯

go4 Sat 24 Jun

I have written such api: getPixel and setPixel,

Example code:

//if you work in FWT
FwtToolkitEnv.init

Image p := BufImage.fromUri(`fan://icons/x16/folder.png`) |p|
{
  //image filter
  for (i:=0; i < p.size.w; ++i)
  {
    for (j:=0; j < p.size.h; ++j)
    {
      c := p.getPixel(i,j)
      //echo(c)
      c = c.and(0xffff0000)
      //echo(c)
      p.setPixel(i, j, c)
    }
  }
}
g := FwtToolkitEnv.toGraphics(g1)
g.drawImage(p, 0, 0)

Kevin Sun 25 Jun

This is awesome! Thanks!

(However, I did my program in Java already...)

Login or Signup to reply.