Drawing scaled images onto a canvas

26 views
Skip to first unread message

Brigt Vik

unread,
Sep 7, 2016, 5:58:04 AM9/7/16
to PlayN


I'm migrating from PlayN 1.9 to 2.0 now, and I'm running into a snag. I used to create SurfaceImages and drawing various images onto them, which worked fine, but SurfaceImage isn't available in 2.0, so I think Canvas is what I need for that instead.

Drawing into a Canvas works fine for the most part, but it's looking bad with jagged edges when I draw them scaled. Apparently antialiasing isn't applied?

Adding an ImageLayer and setting the scale draws them properly on the screen, as can be seen on the screenshot. I'd like for drawing scaled into a Canvas to also produce nice antialiased edges, and I'm hoping it's just me being blind to how I can enable that.

Here's the code creating the screenshot above (the project is created from the 2.0-rc3 archetype and not modified in any other way than the core class below). You can get the full project from https://github.com/brigtvik/playn if you want.

public class Test extends SceneGame
{
   
public Test(Platform plat)
   
{
       
super(plat, 33); // update our "simulation" 33ms (30 times per second)

       
Image testImage = plat.assets().getImage("images/user_add.png");
        testImage
.state.onSuccess(new LoadThemUp(this));
   
}

   
private class LoadThemUp extends Slot<Image>
   
{
       
private Test game;

       
public LoadThemUp(Test game)
       
{
           
this.game = game;
       
}

       
@Override
       
public void onEmit(Image image)
       
{
           
//Add Canvas layers at different scales, looking bad
           
float x = 0;
           
float y = 0;
           
for(float scale = 0.7f; scale < 1.3f; scale += 0.1f)
           
{
               
float width = image.width() * scale;
               
float height = image.height() * scale;
               
CanvasLayer layer = new CanvasLayer(game.plat.graphics(), width, height);
               
Canvas canvas = layer.begin();
                canvas
.draw(image, 0, 0, width, height);
                layer
.end();
                layer
.setTranslation(x, y);
                game
.rootLayer.add(layer);
                x
+= width;
           
}

           
//Add Image layers at the same scales, looking good
            x
= 0;
            y
+= 200;
           
for(float scale = 0.7f; scale < 1.3f; scale += 0.1f)
           
{
               
float width = image.width() * scale;
               
ImageLayer layer = new ImageLayer(image);
                layer
.setScale(scale, scale);
                layer
.setTranslation(x, y);
                game
.rootLayer.add(layer);
                x
+= width;
           
}
       
}
   
}
}

Michael Bayne

unread,
Sep 7, 2016, 3:04:50 PM9/7/16
to pl...@googlegroups.com
On Wed, Sep 7, 2016 at 2:58 AM, Brigt Vik <bov...@gmail.com> wrote:
I'm migrating from PlayN 1.9 to 2.0 now, and I'm running into a snag. I used to create SurfaceImages and drawing various images onto them, which worked fine, but SurfaceImage isn't available in 2.0, so I think Canvas is what I need for that instead.

Use TextureSurface. It's what SurfaceImage used to be but more general purpose.

Michael Bayne

unread,
Sep 7, 2016, 3:06:56 PM9/7/16
to pl...@googlegroups.com

On Wed, Sep 7, 2016 at 12:04 PM, Michael Bayne <m...@samskivert.com> wrote:
Use TextureSurface. It's what SurfaceImage used to be but more general purpose.

To be clear, instead of bundling a texture and surface together in a SurfaceImage, with other things hidden behind the scenes. Now you just create a TextureSurface with your desired dimensions and it's a Surface, so you can render to it, but it's also a Texture so you can create an ImageLayer with it (or draw it directly to the Surface in paint() or whatever).

Brigt Vik

unread,
Sep 8, 2016, 4:13:01 AM9/8/16
to PlayN
That sounds lovely! Thank you, I'll be switching over to that. I failed to find any sample using it though, so I'll add my small test code here for any others looking into it. Feel free to point out any blunder I'm doing there, of course.

            //Add TextureSurface layers at the same scales
            x
= 0;
            y
+= 150;

           
for(float scale = 0.7f; scale < 1.3f; scale += 0.1f)
           
{
               
float width = image.width() * scale;
               
float height = image.height() * scale;

               
TextureSurface surface = new TextureSurface(game.plat.graphics(), game.defaultBatch, width, height);
               
Surface s = surface.begin();
                s
.setFillColor(0xFFFFFFFF);
                s
.drawLine(0, 0, width, 0, 1);
                s
.drawLine(0, 0, 0, height, 1);
                s
.drawLine(0, height, width, height, 1);
                s
.drawLine(width, 0, width, height, 1);
                s
.draw(image.tile(), 0, 0, width, height);
                surface
.end();
               
ImageLayer layer = new ImageLayer(surface.texture);
Reply all
Reply to author
Forward
0 new messages