mgraphics append shapes to image()

MIB's icon

Quick question about the image() function in mgraphics. I need to draw an image, display it, update/append data to it. Is that possible?

Background: I need to draw 2000+ shapes in the jsui object incrementally building up my picture as I go (this is timed, sort of like an animation). So I have a counter that goes through my array of pre-calculated shapes. Of course only the shape at the current counter number is displayed. So I used a for loop to loop through the entire array up to the counter number. Works fine until the CPU comes to a grind because of the number of shapes. So I thought I could draw my context to an image and then append new shapes to that image, drawing 1 image instead of thousands of shapes...

Is this the correct approach? thanks

MIB's icon

here is some code I am playing with right now. What I don't understand is why the image keeps offsetting on each bang message. With each iteration the image seems to shift by a couple of pixels in the x and y direction... nice effect but not what I am after. why is this happening? Screenshot attached as well...

inlets = 1;
outlets = 2;
autowatch = 1;

mgraphics.init();
mgraphics.relative_coords = 0;
mgraphics.autofill = 0;

var curImage                = new Image();

var width                     = box.rect[2] - box.rect[0];
var height                     = box.rect[3] - box.rect[1];
/************************/
function paint()
{    
    mgraphics.set_line_width(2.);
    mgraphics.set_source_rgba(1., 0., 0., 1.);
            
    
        
    with (mgraphics)    {            
        
        push_group();        
                
        image_surface_draw(curImage);  //draw old image
        curImage.freepeer();    
            
        //add more shapes
        set_source_rgb(Math.random(), Math.random(), Math.random());
        set_line_width(5);
        rectangle(0, 0, width- 5, height-5);
        stroke();
        
        rectangle(Math.random() * width, Math.random() * height, 50, 50);
        
        
        
        set_source_rgb(Math.random(), Math.random(), Math.random());
        
        fill();
                
            
        //save as new image
        curImage = new Image(pop_group());

        //draw the new image
        image_surface_draw(curImage);
    
    }
    
    post("image size = ", curImage.size, "\n");
}
/************************/
function bang()
{
    mgraphics.redraw();
}
/************************/
Untitled1.png
png
do.while's icon

Hi !
the 2px offset its weird ! dont know . cant explain it .

inlets = 1;
outlets = 2;
autowatch = 1;

mgraphics.init();
mgraphics.relative_coords = 0;
mgraphics.autofill = 0;

var curImage                = new Image();

var width                     = box.rect[2] - box.rect[0];
var height                     = box.rect[3] - box.rect[1];
/************************/
function paint()
{    
    mgraphics.set_line_width(2.);
    mgraphics.set_source_rgba(1., 0., 0., 1.);
            
    
        
    with (mgraphics)    {            
        translate(-2,-2); // HEEEEEEEEREEE I AM
        push_group();        
                
        image_surface_draw(curImage);  //draw old image
        curImage.freepeer();    
            
        //add more shapes
        set_source_rgb(Math.random(), Math.random(), Math.random());
        set_line_width(5);
        rectangle(0, 0, width- 5, height-5);
        stroke();
        
        rectangle(Math.random() * width, Math.random() * height, 50, 50);
        
        
        
        set_source_rgb(Math.random(), Math.random(), Math.random());
        
        fill();
                
            
        //save as new image
        curImage = new Image(pop_group());

        //draw the new image
        image_surface_draw(curImage);
    
    }
    
    post("image size = ", curImage.size, "\n");
}
/************************/
function bang()
{
    mgraphics.redraw();
}
/************************/

a hack would be a translate . its offseting back these 2px .

MIB's icon

This seems to work better. Is this efficient?

inlets = 1;
outlets = 2;
autowatch = 1;

mgraphics.init();
mgraphics.relative_coords = 0;
mgraphics.autofill = 0;

var curImage    = new Image();

var width = box.rect[2] - box.rect[0];
var height = box.rect[3] - box.rect[1];
/************************/
function paint()
{    
mgraphics.set_line_width(2.);
mgraphics.set_source_rgba(1., 0., 0., 1.);

with (mgraphics)    {    

image_surface_draw(curImage);

}

post("image size = ", curImage.size, "\n");
}
/************************/
function bang()
{    
makeImage();

mgraphics.redraw();
}
/************************/
function makeImage()
{

var canvas = new MGraphics(width, height);

canvas.image_surface_draw(curImage);

canvas.set_source_rgb(getRandomColour());
canvas.set_line_width(5);
canvas.rectangle(0, 0, width- 5, height-5);
canvas.stroke();

canvas.rectangle(Math.random() * width, Math.random() * height, 50, 50);

canvas.set_source_rgb(Math.random(), Math.random(), Math.random());

canvas.fill();

curImage = new Image(canvas);
}
/************************/
deligut's icon

I should think that the creation of the MGraphics drawing context "var canvas= new MGraphics(width,height)" should be outside the function makeImage(). I guess on every call of function makeImage() your are now creating another new MGraphics drawing context and they all draw on top of each other. This may slow down or eventualls even crash the program. To avoid this I would place the "var canvas= new MGraphics(width,height)" at the very beginning above the function paint().