Page 1 of 2

VPI Picture

Posted: 30 Mar 2008 20:26
by vjoer
Hello

I use the VPI picture handling to draw some basic geometries onto a picture canvas.
I extract the picture using

Code: Select all

Picture = drawingCanvas:getPicture().
Afterwards I save the picture to a file using:

Code: Select all

        vpi::pictSave(Picture, FullFilename),         vpi::pictDestroy(Picture).
..and i want to be able to draw again onto the canvas.

However when i try to , i get a message about
No attached VPI window.


The VPI help said that redrawing is possible with setSize but it still did not work.

Any suggestions?

Regards

Posted: 30 Mar 2008 21:27
by Paul Cerkez
vjoer,

when you invoked vpi::pictdestroy() there is nothing left to draw on. you have removed the handle to the device context. (note that htis also an obsolete predicate and now does nothing in VIP 7.1 and I am not sure how many releases back)

you will either need to do your drawing BEFORE you delete it or start a new "canvas."

Posted: 31 Mar 2008 6:54
by vjoer
Hello Paul

I had tried also this approach but it failed with error "Too many open pictures".

What am i missing here?

Regards

Posted: 31 Mar 2008 12:25
by Paul Cerkez
unfortunately I am work right now and my code for this is at home but I have had my project tool create hundreds of pictures and save them with no problems.

I haven't looked at that partiular code in months but I don't think I recreate the DC everytime, I think I use the existing one, clear the current image, start drawing again then save it. I will try to look the code up when I get home tonight.

P.

Posted: 1 Apr 2008 0:39
by Paul Cerkez
from my code:

what I do is create a class fact (single) to holds the handle of the pict canvas.

Code: Select all

class facts     picWin : pictureCanvas := erroneous.
then after each save, I simply re-run the predicate that does the drawing.

Code: Select all

    drawGraphic(...):-                 ...         controlRCT = rct(...),         picWin := pictureCanvas::new(X,Y),         picWin : setFont(vpi::fontCreateByName("MS Sans Serif",titleFontSize)),         picWin : setForeColor(color_black),           ...         picWin : drawTextInRect(...),         PIC = picWin:getPicture(),         FileName = string::concat( ...),         vpi::pictSave(PIC, FileName).   clauses     cycleThrough():-          ...             %  create 10 different version, use for loop.        foreach Counter = std::fromTo(1,10) do            drawGraphic(Counter)        end foreach,        ...        fail.    cycleThrough().
as part of that, I save the new canvas handle to the class fact. the VIP garbage ccollector cleans up the old one as it is not longer referenced.

my little program generates 60 images in about 1 or 2 seconds with no problems. I am working on it to produce about 1000 to 10000 once I dispose of some other problems (work related).

hope this helps

P.

Posted: 1 Apr 2008 6:51
by vjoer
Thank you

Posted: 3 Aug 2009 23:52
by Paul Cerkez
Thomas,
In regards to this earlier discussion....

what kicks the garbage collector in and when does it recover memory?

I've tried including it in my code but no joy.

in my BMP generation application, as soon as I hit 9941 images, the application crashes. This equates to 1.9G worth of files.

as the application is running, I watch memory usage in the windows task monitor continue to climb until the application crashes at approximately 1.98G to 2.04G.

here is the block of code where I create the images:

Code: Select all

    drawGraphicMorse(INint):- /*"MS Sans Serif"*/        % not used any more %        Offset= 10,         IN = toString(INint),         controlRCT = rct(_X1,_Y1,X2,Y2),         picWin := pictureCanvas::new(256,256),         picWin : setFont(vpi::fontCreateByName("Courier New",titleFontSize)),         picWin : setForeColor(color_black),           RAW = raw_Input_text,           translateor::translateor(RAW, MOrse, _ISOMORPH),           XT =convert(integer, math::random(220)),         YT = convert(integer, math::random(220)),         picWin : drawTextInRect(rct(XT,YT,X2,Y2),Morse, [dtext_Left ,dtext_Wordbreak]),         PIC = picWin:getPicture(),         FileName = string::concat("MORSE ", RAW, "-", IN, ".BMP"),         vpi::pictSave(PIC, FileName),         picWin := erroneous,   % to release reference to the context         fail.  % to further release reference       drawGraphicMorse(_INint):-!.   % to ensure "succcess"
note that this is the only place where the picture canvas is used or referenced

the calling code operates the same way:

Code: Select all

    cycleThrough():-         %retract value off database         retract(textToEncode(X)),         raw_Input_text:= X,            % set the new folder         directory::setCurrentDirectory("E:/research/SourcePhotos/Set -1-2/Morse"),         % create the MOrse version        foreach Counter = std::fromTo(1,10) do             %  create 10 different version, using for loop.             randomFontSize(),             drawGraphicMorse(Counter)        end foreach,           ...           memory::garbageCollect(),           fail.               cycleThrough().        
I assume I am hitting a 32 bit memory boundry, but why am I not getting free memeory back?

is there anyway to recover this memory?

P.

Posted: 4 Aug 2009 0:42
by Paul Cerkez
well, something else is going on here, it is not the OS. When I run the application, memory jumps almost immediately to 2.04 G and stays there until the application crashes.

the application runs then simply crashes at 9941 BMP files created.

I am assuming it is is in VIP memory and my use of it.

when I try to create a single pictureCanvas and reuse it, I get exceptions that lead to setFont has no window handle. ("No attached VPI window.")

when I create the canvas fresh each time, I don't get any errors except the crash at 9941 files.

for now, until I have time to research it more, I will just limit my batch processing to 9000 files at a time.

P.

Posted: 4 Aug 2009 6:55
by Roland Soltysiak
Hello Paul,

I know this 99xx problem. If you do not use setFont, you will not get a crash.

I know also the memory problem but from 7.2 on it works really fine.

I had discussed it with Yuri here:

http://discuss.visual-prolog.com/viewto ... ght=#24463


Regards
Roland

Posted: 4 Aug 2009 11:47
by Paul Cerkez
That is interesting. Thank you

I also noticed another problem, when I try to move the pictureCanvas context out of the current clause and raise it up to a class level, the application will compile fine but as soon as I invoke the routine, it throughs an exception at the setFont call.

when I get home tonight, I will try the application with setfont disabled and see what happens.

my problem is , I need the setfont call.

P.

Posted: 5 Aug 2009 2:44
by Paul Cerkez
the problem absolutely is with setFont.

I commented the call to setFont out, recomiled and created 47,400 BMP images with no problems.

this is definitely a bug.

Posted: 6 Aug 2009 21:22
by Thomas Linder Puls
FYI: We will investigate this problem.

Posted: 7 Aug 2009 1:06
by Paul Cerkez
thank you.

(created another 110,000 BMP images last night with no problems with setFont disabled.)

Where is this pictureCanvas code embedded?

Posted: 3 Aug 2013 14:01
by Ferenc Nagy
Hi Paul,
Where is this pictureCanvas code embedded?
In a form?
What is the place of the drawGraphic(...) call?

Please attach the surrounding level.
Paul Cerkez wrote:from my code:

what I do is create a class fact (single) to holds the handle of the pict canvas.

Code: Select all

class facts     picWin : pictureCanvas := erroneous.
then after each save, I simply re-run the predicate that does the drawing.

Code: Select all

    drawGraphic(...):-                 ...         controlRCT = rct(...),         picWin := pictureCanvas::new(X,Y),         picWin : setFont(vpi::fontCreateByName("MS Sans Serif",titleFontSize)),         picWin : setForeColor(color_black),           ...         picWin : drawTextInRect(...),         PIC = picWin:getPicture(),         FileName = string::concat( ...),         vpi::pictSave(PIC, FileName).   clauses     cycleThrough():-          ...             %  create 10 different version, use for loop.        foreach Counter = std::fromTo(1,10) do            drawGraphic(Counter)        end foreach,        ...        fail.    cycleThrough().
P.

Posted: 5 Aug 2013 11:11
by Paul Cerkez
Frank,
It was available in 7.2,

this was the 'header' in the file i used it in:

Code: Select all

implement graphicMorse     inherits userControlSupport     open core, vpiDomains

P.