I need these for animation\image filter\out screen buffer. Is it on the roadMap?
brianWed 21 Jul 2010
Just so we are clear, what features exactly are you asking for?
buffered images with ability to get Graphics context
serialization to png, jpeg, gif
go4Fri 23 Jul 2010
That would be nice. I just want to do some cool effects, like the Flash done.
brianMon 26 Jul 2010
Renamed from Image API ? to Image API enhancements
brianMon 26 Jul 2010
Promoted to ticket #1156 and assigned to brian
brianMon 3 Jan 2011
Ticket reassigned from brian to andy
Yuri StrotWed 16 Feb 2011
Hi,
@ikornienko and I working on the buffered image feature. We've already implemented ability to use Graphics over Image for SWT and JS and before sharing our work I'd like to discuss API.
In SWT (as well as in AWT) any loaded image can be changed using Graphics:
// SWT
GC gc = new GC(image);
// use gc to change image
...
gc.dispose();
// AWT
Graphics g = image.getGraphics();
// use g to change image
...
In JS you can't change existing image (HTML <img>), but you can create canvas, paint your image on this canvas, paint something else and then create new image. This approach looks better for Fantom where Image is a const object.
During discussion with Brian we found useful to have two classes: const Image and mutable ImageBuf (similar to sys::Str and sys::StrBuf). The workflow is following:
buf := ImageBuf(w, h) // or ImageBuf.makeImage(image)
g := buf.getGraphics
g.drawImage(image, 0, 0)
//use g to change image
...
newImage := buf.toImage
Does this API work for everyone?
brianThu 17 Feb 2011
Thanks for posting @ystrot.
I still haven't figured out what best design should be, but here are some random thoughts:
in general I've always found "buffered images" that you can paint versus images loaded from static files like PNG are often sort of confusing
having Image be const is a good thing because most images are loaded from a file and its nice to immutability pass them around to stick in labels, etc
because Image is const, we can't create a BufferedImage subclass which isn't const
Here are some (not fully thought out) proposals:
a) use Str / StrBuf model as proposed by ystrot:
class ImageBuf // does *not* subclass Image
{
Graphics graphics
Image toImage()
}
Although I should not there are still some tricky things about toImage since you don't want it backed by the mutable buffered image (or at least you need to do a bitblt copy if someone tries to mutate the ImageBuf).
b) Maybe some sort of closure based factory on Image?
That seems pretty elegant and simple, however it has the huge downside that we have to reallocate the image memory and repaint it even if you just want to make a minor change to a few pixels (so by itself that doesn't seem workable)
c) Maybe create some new term which has absolutely no relationship to Image:
class PixelGrid { Graphics graphics() }
class Graphics
{
Void drawImage(...)
Void drawPixelGrid(...)
}
Although to tell you the truth I don't really love either one of those.
go4Thu 17 Feb 2011
Some ideas:
List model (List.toImmutable):
class Image
{
override This toImmutable(){...}
Graphics graphics(){ if(!immutable) throw Err() }
}
Image interface:
mixin Image{}
const class ConstImage : Image {}
class ImageBuf : Image
{
Graphics graphics()
}
Yuri StrotThu 17 Feb 2011
I like idea of closure based factory on Image. It looks useful for major tasks with buffered images (double-buffering and custom image rendering). In the future we can extend API and replace native implementation:
static native Image makeBuf(Int w, Int h, |Graphics| it)
with something more appropriate without breaking changes. For example:
So I think b) is something we can stay with for now.
andyMon 21 Feb 2011
If you are planning on rendering to the Image more than a single time, I believe the proper solution there should be Canvas. So to me, I think this only a hook for dynamically generating an Image - but from there on its const - in order to use it places that accept Image (like Label for example). In which case the simplest solution would be a static factory makeBuf method. And we also avoid to complexity of dual types.
brianTue 22 Feb 2011
Been thinking about for a while too, and agree with Andy. While there are certainly use cases for keeping a mutable Image buffer around for constant redraw, the vast majority of those can be handled by a double buffered Canvas (where you can control selective repaints of dirty regions).
So what I would suggest as action items:
Add new factory to Image
Add double buffering support to Canvas
For the Image factory, only trick is what to call it. I don't really like makeBuf since it implies all sorts of details related to SWT and AWT. How about:
static Image makePainted(Int w, Int h, |Graphics| f)
If everyone is in agreement with that initial direction, I can work with @ystrot on getting those into next build.
Yuri StrotTue 22 Feb 2011
1) Works well for me. However makePainted looks too verbose... How about static draw method?
static native Image draw(Int w, Int h, |Graphics| f)
Is there any reason to make this method ctor and start with make?
2) Do you want to provide double buffering by default?
brianTue 22 Feb 2011
I debated about the makePainted versus simple name like just draw or paint. I could go with a simple verb, sort of breaks conventions to scan the slot list looking for the "make" prefix, but still probably easily discoverable in a small class like Image. Although I think paint would probably be better than draw since we use paint as the top-level for classes in Widget, etc.
I would say double buffering is not the default for Canvas, but I don't have a strong opinion (haven't thought about it much)
Yuri StrotTue 22 Feb 2011
OK, I'll create a patch tomorrow.
I'm going to look at double buffering deeply. With current implementation I've found that HTML5 canvas not require double buffering (no flickering). Therefore I used a trick to provide buffering in Java and avoid it in JS.
rfeldmanTue 22 Feb 2011
Is the lack of flickering true in all browsers? I remember trying out Canvas in Firefox months ago and seeing flickering, but maybe they switched to double buffering since then...
Many thanks to @ystrot who got the Image.makePainted factory implemented for both SWT and JS.
This original ticket was for 2 issues:
buffered images
support for image I/O to read/write png, jpeg, etc
Buffered images is done now with the new makePainted method, so I am going to close out this ticket.
We should probably create a new ticket for png/jpeg I/O. Is there anyone interested in helping with those APIs? I haven't done any investigation to see what support SWT provides for that.
go4 Wed 21 Jul 2010
I found the FWT API is not enough to use.
I need these for animation\image filter\out screen buffer. Is it on the roadMap?
brian Wed 21 Jul 2010
Just so we are clear, what features exactly are you asking for?
go4 Fri 23 Jul 2010
That would be nice. I just want to do some cool effects, like the Flash done.
brian Mon 26 Jul 2010
Renamed from Image API ? to Image API enhancements
brian Mon 26 Jul 2010
Promoted to ticket #1156 and assigned to brian
brian Mon 3 Jan 2011
Ticket reassigned from brian to andy
Yuri Strot Wed 16 Feb 2011
Hi,
@ikornienko and I working on the buffered image feature. We've already implemented ability to use Graphics over Image for SWT and JS and before sharing our work I'd like to discuss API.
In SWT (as well as in AWT) any loaded image can be changed using Graphics:
In JS you can't change existing image (HTML <img>), but you can create canvas, paint your image on this canvas, paint something else and then create new image. This approach looks better for Fantom where Image is a const object.
During discussion with Brian we found useful to have two classes: const Image and mutable ImageBuf (similar to
sys::Str
andsys::StrBuf
). The workflow is following:Does this API work for everyone?
brian Thu 17 Feb 2011
Thanks for posting @ystrot.
I still haven't figured out what best design should be, but here are some random thoughts:
Here are some (not fully thought out) proposals:
a) use Str / StrBuf model as proposed by ystrot:
Although I should not there are still some tricky things about toImage since you don't want it backed by the mutable buffered image (or at least you need to do a bitblt copy if someone tries to mutate the ImageBuf).
b) Maybe some sort of closure based factory on Image?
That seems pretty elegant and simple, however it has the huge downside that we have to reallocate the image memory and repaint it even if you just want to make a minor change to a few pixels (so by itself that doesn't seem workable)
c) Maybe create some new term which has absolutely no relationship to Image:
Although to tell you the truth I don't really love either one of those.
go4 Thu 17 Feb 2011
Some ideas:
Yuri Strot Thu 17 Feb 2011
I like idea of closure based factory on Image. It looks useful for major tasks with buffered images (double-buffering and custom image rendering). In the future we can extend API and replace native implementation:
with something more appropriate without breaking changes. For example:
So I think b) is something we can stay with for now.
andy Mon 21 Feb 2011
If you are planning on rendering to the Image more than a single time, I believe the proper solution there should be Canvas. So to me, I think this only a hook for dynamically generating an Image - but from there on its const - in order to use it places that accept Image (like Label for example). In which case the simplest solution would be a static factory
makeBuf
method. And we also avoid to complexity of dual types.brian Tue 22 Feb 2011
Been thinking about for a while too, and agree with Andy. While there are certainly use cases for keeping a mutable Image buffer around for constant redraw, the vast majority of those can be handled by a double buffered Canvas (where you can control selective repaints of dirty regions).
So what I would suggest as action items:
For the Image factory, only trick is what to call it. I don't really like
makeBuf
since it implies all sorts of details related to SWT and AWT. How about:If everyone is in agreement with that initial direction, I can work with @ystrot on getting those into next build.
Yuri Strot Tue 22 Feb 2011
1) Works well for me. However
makePainted
looks too verbose... How about staticdraw
method?Is there any reason to make this method ctor and start with
make
?2) Do you want to provide double buffering by default?
brian Tue 22 Feb 2011
I debated about the makePainted versus simple name like just
draw
orpaint
. I could go with a simple verb, sort of breaks conventions to scan the slot list looking for the "make" prefix, but still probably easily discoverable in a small class like Image. Although I thinkpaint
would probably be better thandraw
since we use paint as the top-level for classes in Widget, etc.I would say double buffering is not the default for Canvas, but I don't have a strong opinion (haven't thought about it much)
Yuri Strot Tue 22 Feb 2011
OK, I'll create a patch tomorrow.
I'm going to look at double buffering deeply. With current implementation I've found that HTML5 canvas not require double buffering (no flickering). Therefore I used a trick to provide buffering in Java and avoid it in JS.
rfeldman Tue 22 Feb 2011
Is the lack of flickering true in all browsers? I remember trying out Canvas in Firefox months ago and seeing flickering, but maybe they switched to double buffering since then...
Yuri Strot Tue 22 Feb 2011
For me it works well in Chrome, Firefox and Opera. But I saw opened issues in stackoverflow which say there is no such support. For example: http://stackoverflow.com/questions/2795269/does-html5-canvas-support-double-buffering
So need a better look...
brian Mon 28 Feb 2011
Ticket resolved in 1.0.58
Many thanks to @ystrot who got the Image.makePainted factory implemented for both SWT and JS.
This original ticket was for 2 issues:
Buffered images is done now with the new makePainted method, so I am going to close out this ticket.
We should probably create a new ticket for png/jpeg I/O. Is there anyone interested in helping with those APIs? I haven't done any investigation to see what support SWT provides for that.