A gray scale image is to be displayed with feature-related lines
overlaid later. The current approach to the initial display is as
follows:
determine image size,
call PhCreateImage(ph_image, …) to obtain managed space (at
ph_image->image)
copy the byte-per-pixel image into ph_image->image
set the region id (which points to a PtLabel of “image”
type)
call PgDrawPhImage()
This works fine: the window containing the PtLabel with the image can
return to the foreground with the image intact. The flags in ph_image
structure are set to release the image and masks. I don’t know
exactly when this happens. But a redraw with a new,
differently-sized image results in a flawless appearance – no code
needed to “paint over” what would have been artifacts of
the previous image.
The next part is not so good. The lines of interest (sets of end
points) are returned from a separate process then transformed into
screen coordinates. In the first trial, lines were copied into the
widget coordinates using PgDrawLine() and the end points. The lines
look good, but when the parent window is returned to the foreground,
the overlaid lines are not there. I sort of understand this. I used
a low-level draw function and the resultant pixels are not managed
like the image-bearing widget.
Trial number two attempted to build lines in ph_image->image by
using the end points and pixels interpolated between them. I assumed
that I could modify points in ph_image->image then invoke
PhDrawPhImage() and one of the “flush” functions to refresh
the image. But what I get is a dead Photon process! (Perhaps the
call to PhDrawPhImage results in the release of all the ph_image
pointers and storage.)
Boil all this down my main questions are these:
How to display one PhImage then modify it later?
How to use line drawing functions to do this?
Where is documentation about draw contexts?
Can one use other low-level draw functions with PhImag_t types.
My best guess: build an entirely new image using the same original
array but insert the lines then call
PhDrawPhImage().
I don’t use PgDraw… functions. I modify the image in memory
and then call PtDamageWidget or PtDamageExtent to redraw.
It works fine.
To use PgDraw… functions, you can create your own memory context
to draw in memory with PhMemCreateMC (your_image, …)
then PgMemStart (your_MC), PgDraw… (all what you need),
PgMemFlush, PgMemStop,
and then PtDamageWidget or PtDamageExtent.
For me, it works too.
A gray scale image is to be displayed with feature-related lines
overlaid later. The current approach to the initial display is as
follows:
determine image size,
call PhCreateImage(ph_image, …) to obtain managed space (at
ph_image->image)
copy the byte-per-pixel image into ph_image->image
set the region id (which points to a PtLabel of “image”
type)
call PgDrawPhImage()
This works fine: the window containing the PtLabel with the image can
return to the foreground with the image intact. The flags in ph_image
structure are set to release the image and masks. I don’t know
exactly when this happens. But a redraw with a new,
differently-sized image results in a flawless appearance – no code
needed to “paint over” what would have been artifacts of
the previous image.
The next part is not so good. The lines of interest (sets of end
points) are returned from a separate process then transformed into
screen coordinates. In the first trial, lines were copied into the
widget coordinates using PgDrawLine() and the end points. The lines
look good, but when the parent window is returned to the foreground,
the overlaid lines are not there. I sort of understand this. I used
a low-level draw function and the resultant pixels are not managed
like the image-bearing widget.
Trial number two attempted to build lines in ph_image->image by
using the end points and pixels interpolated between them. I assumed
that I could modify points in ph_image->image then invoke
PhDrawPhImage() and one of the “flush” functions to refresh
the image. But what I get is a dead Photon process! (Perhaps the
call to PhDrawPhImage results in the release of all the ph_image
pointers and storage.)
Boil all this down my main questions are these:
How to display one PhImage then modify it later?
How to use line drawing functions to do this?
Where is documentation about draw contexts?
Can one use other low-level draw functions with PhImag_t types.
My best guess: build an entirely new image using the same original
array but insert the lines then call
PhDrawPhImage().
I will look into the memory context option. (By the way, those
functions are prefixed with “Pm” not “Ph” in the
Photon Library Reference.) I am especially hopeful to use
PgDraw-type utilities rather than hack my own line drawing routines.
Have you looked in to using a PtRaw widget? In this widget you can draw
your grayscale image where you want. You will setup a draw handler that
will get called each time the widget is supposed to draw.
How to use line drawing functions to do this?
If you use a PtRaw widget, then in the draw handler that you setup, you
can determine where you want to draw your lines based on the data that
you obtain using low level draw functions (PgDrawLine, etc).
Where is documentation about draw contexts?
You didn’t say what version of the OS you are using, so I went with
6.3.0 SP3. I would suggest you read this section of the photon docs:
Can one use other low-level draw functions with PhImag_t types.
If you setup a memory context that is your image then sure. I think it
would be faster though if you draw your image, and then draw stuff on
top of it, using the PtRaw widget.
My best guess: build an entirely new image using the same original
array but insert the lines then call
PhDrawPhImage().
Thanks for your input. Earlier, I did look at the documentation for
PtRaw widget but, being simpled-minded and lazy, I was hoping for a
quick and easy solution. Now it looks like I will have to actually
think to implement the two-phase drawing.
My single draw function to PtRaw will have to supply both a 2D image
and a list of lines. When the image is previewed, only the image
argument will be non-null. A bit later, when the line data arrives,
the draw function will also have end point pairs (and colors, etc.)
for PgDrawLine to use. This, I hope, will produce a widget that,
when reappearing in the foreground, will retain both the image and
the overlaid lines.
You can set data on a widget. Might I suggest creating a structure that
contains the image data and your line data. Then in your draw routine
get the widget data and check the structure. If you have an image in
the structure, then draw it. If you have line data in the structure
then draw it as well. It can all be done within the same drawing routine.
I honestly think that you’ll find the PtRaw widget fairly simple to
implement, once you start playing around with it.
Thanks,
Rodney
rlb wrote:
Rodney,
Thanks for your input. Earlier, I did look at the documentation for
PtRaw widget but, being simpled-minded and lazy, I was hoping for a
quick and easy solution. Now it looks like I will have to actually
think to implement the two-phase drawing.
My single draw function to PtRaw will have to supply both a 2D image
and a list of lines. When the image is previewed, only the image
argument will be non-null. A bit later, when the line data arrives,
the draw function will also have end point pairs (and colors, etc.)
for PgDrawLine to use. This, I hope, will produce a widget that,
when reappearing in the foreground, will retain both the image and
the overlaid lines.
As to associating data with a widget, I see that’s what
Pt_ARG_USER_DATA and Pt_ARG_POINTER are for. I was actually almost
there a few days ago furnishing image and line data to a function
manipulating the buffer returned by PhCreateImage(). But the line
drawing proved a problem. Yup, PtRaw is the way to go.