#2547 gfx::Image Creation from IntArray

Jay Herron Sun 3 Jul 2016

Hi,

Does anyone know of a way to create a gfx::Image from an IntArray that is holding a byte array representation of an image (in a *.jpg format). I'm looking for something similar to the 'createImage' method of the java Toolkit, seen here: `https://docs.oracle.com/javase/7/docs/api/java/awt/Toolkit.html#createImage(byte[])`

Thanks!

SlimerDude Sun 3 Jul 2016

Hi Jay,

If you stick your data in a Buf then you could use "in memory files" like this:

buf   := ...
file  := buf.toFile(`any/old/unique/uri`)
image := Image.makeFile(file)

But you'd have to build Fantom from source as "in memory files" were added after the Fantom 1.0.68 release - see this commit.

I believe at one point there was some talk of a Fantom nightly build, but that seems to have lost traction.

Otherwise you may just have to save the data as a temporary file, and re-load it... :(

(Oh, and Bufs are a better / more compact / more convenient way to hold binary data than Int arrays.)

SlimerDude Mon 4 Jul 2016

Hi Jay,

I had another look at your problem and here's a different solution...

It creates an SWT Image from a Buf and does some native fwt fiddling to copy the contents into a new Fantom Image:

using [java] fanx.interop::Interop
using [java] fan.fwt::FwtGraphics
using [java] org.eclipse.swt.graphics::Image as SwtImage
using [java] org.eclipse.swt.widgets::Display as SwtDisplay
using gfx::Image
using gfx::Size

...

Image makeImageFromBuf(Buf buf) {
    swtImg  := SwtImage(SwtDisplay.getCurrent ?: SwtDisplay(), Interop.toJava(buf.seek(0).in))
    imgSize := Size(swtImg.getBounds.width, swtImg.getBounds.height)
    fanImg  := Image.makePainted(imgSize) |gfx| {
        fwtGfx := (FwtGraphics) gfx
        fwtGfx.gc.drawImage(swtImg, 0, 0)
    }
    return fanImg
}

But note your new Fantom images loose all transparency information due to this ongoing ticket.

SlimerDude Mon 4 Jul 2016

Not to be beaten, here's a solution that gets round the transparency issue:

using gfx::Size
using gfx::Image
using [java] fan.fwt::Fwt
using [java] fan.fwt::FwtGraphics
using [java] fanx.interop::Interop
using [java] org.eclipse.swt.graphics::Image as SwtImage
using [java] org.eclipse.swt.widgets::Display as SwtDisplay

...

Image makeImageFromBuf(Buf buf) {
    swtImg  := SwtImage(SwtDisplay.getCurrent ?: SwtDisplay(), Interop.toJava(buf.seek(0).in))
    imgSize := Size(swtImg.getBounds.width, swtImg.getBounds.height)
    imgUri  := `mem-${Uuid()}`
    fanImg  := Image.makeFields(imgUri, ``.toFile)  // Fantom Bug - File param should be nullable
    images  := Interop.toJava(Fwt#).getDeclaredField("images")
    images.setAccessible(true)
    images.get(Fwt.get)->put(imgUri, swtImg)
    return fanImg
}

Jay Herron Tue 5 Jul 2016

Awesome! Thanks so much for your help!

Login or Signup to reply.