I have an image of the seafloor(.jpg) and I want to draw a simple 3x3
grid over it that the user can toggle on and off. Currently, when the
user tells the program to skip to the next image I set a static bitmap
to a wxBitMapFromImage. I've been doing some research and I think I
may need to use a DC to draw a grid on the image before I turn it into
a bitmap, but this could be completely off base. This is the first
time I have worked with images in wxPython and I'm having trouble
figuring this out. Thanks in advance.
Hey there! Maybe you can follow my thread, too. It's named "Painting,
blitting...". My question seems to be similar to your's!
I would assume you could just draw an overlay on top of the picture. You can check out the Whyteboard project to see how to draw various shapes on to an image: https://launchpad.net/whyteboard
Once you know how to do that, I would just grab the image’s size and draw the grid programmatically. There are some text overlay examples in one of the examples on this page: http://wiki.wxpython.org/WorkingWithImages
- Mike
There are a number of approaches that could be used, and which is best depends on the needs of your application. You could draw it all yourself without using a separate wx.StaticBitmap, for example in a paint event for the parent window draw the bitmap and then draw the grid. Or you could create a new bitmap from the original image plus the grid, using a wx.MemoryDC, and then either draw the new bitmap, or use it in a wx.StaticBitmap, etc.
You should take a look at the ScrolledWindow sample in the demo (or several others in the demo or the wiki) for an example of drawing things on windows.
···
On 4/11/11 9:41 AM, PRobbins wrote:
I have an image of the seafloor(.jpg) and I want to draw a simple 3x3
grid over it that the user can toggle on and off. Currently, when the
user tells the program to skip to the next image I set a static bitmap
to a wxBitMapFromImage. I've been doing some research and I think I
may need to use a DC to draw a grid on the image before I turn it into
a bitmap, but this could be completely off base. This is the first
time I have worked with images in wxPython and I'm having trouble
figuring this out. Thanks in advance.
--
Robin Dunn
Software Craftsman
This needs just a basic understanding of the DC bitmap drawing tool and a very little algebra.
Ray Pasco
DrawGridOnBitmapPaintDC.PY (3.5 KB)
Thanks for the help. One point I'm a little confused on...when
exactly is Paint event actually called? In my application the image
shows up on the screen unchanged at first. The user can choose a
radio button for a 3x3, 6x6, 9x9 grid or no grid at all. I need the
grid to show up as soon as the radio button is selected. Will a paint
event be called? If not, can I manually call a paint event?
···
On Apr 12, 4:08 pm, Ray Pasco <pascor22...@gmail.com> wrote:
<https://lh3.googleusercontent.com/_2DvUrnDWjI4/TaSw5KQKMvI/AAAAAAAAAC...>
This needs just a basic understanding of the DC bitmap drawing tool and a
very little algebra.Ray Pasco
DrawGridOnBitmapPaintDC.PY
3KViewDownloadGuidoInTheComfyChair.PNG
358KViewDownload
Hi,
···
On Wed, Apr 13, 2011 at 9:11 AM, PRobbins <pjrobbins89@gmail.com> wrote:
Thanks for the help. One point I'm a little confused on...when
exactly is Paint event actually called? In my application the image
shows up on the screen unchanged at first. The user can choose a
radio button for a 3x3, 6x6, 9x9 grid or no grid at all. I need the
grid to show up as soon as the radio button is selected. Will a paint
event be called? If not, can I manually call a paint event?
Yes, simply call Refresh() on the window that is bound to the paint event.
Cody
Ok I have implemented your suggestions and I can see bits of the grid
sticking out from behind the image now and whenever the image
refreshes I can briefly see the grid flash on the screen before it is
covered up by the image. Any idea what's going on? How can I make my
image transparent and/or put the grid on top? Sorry if some of these
questions are elementary, this is really the first time I've worked
with images in wxPython before.
···
On Apr 12, 4:08 pm, Ray Pasco <pascor22...@gmail.com> wrote:
<https://lh3.googleusercontent.com/_2DvUrnDWjI4/TaSw5KQKMvI/AAAAAAAAAC...>
This needs just a basic understanding of the DC bitmap drawing tool and a
very little algebra.Ray Pasco
DrawGridOnBitmapPaintDC.PY
3KViewDownloadGuidoInTheComfyChair.PNG
358KViewDownload
Hi,
Ok I have implemented your suggestions and I can see bits of the grid
sticking out from behind the image now and whenever the image
refreshes I can briefly see the grid flash on the screen before it is
covered up by the image. Any idea what's going on? How can I make my
image transparent and/or put the grid on top? Sorry if some of these
questions are elementary, this is really the first time I've worked
with images in wxPython before.
Can't say without knowing what your doing.
Please make a runnable, small as possible sample
(MakingSampleApps - wxPyWiki) that demonstrates the
problem.
I also attached a simple example that you can try out.
Regards,
Cody
paint.py (2.3 KB)
···
On Wed, Apr 13, 2011 at 9:50 AM, PRobbins <pjrobbins89@gmail.com> wrote:
My application is quite large so I'm not sure I can make a small
enough sample. Here is the relevant code from my program however:
First I am creating a panel and putting a Static Bitmap on it:
self.browserPanel = wx.Panel(self)
self.fgs=wx.FlexGridSizer(cols=1, hgap=1, vgap=1)
#Creat a Static bitmap with a dummy image
self.ibrowserBitmap = wx.StaticBitmap(self, -1,
wx.EmptyBitmap(50,50))
self.fgs.Add(self.ibrowserBitmap)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.loadCurrentImage()
Second, here is the function loadCurrentImage():
def loadCurrentImage(self):
'''
Loads the current image based off Workspace.currentImageIndex.
This function is called after every image change.
'''
try:
self.currentImage = Workspace.data.getImageDirectory() +
os.sep + Workspace.data.getImageName(Workspace.currentImageIndex)
except:
Workspace.currentImageIndex = 1
self.img = simple_image.Image()
if enhanceTool.norm.GetValue()==True:
self.img.normalize('RGB')
if enhanceTool.norm.GetValue()==False:
self.img.normalize(None)
if enhanceTool.eq.GetValue()==True:
self.img.equalize('RGB')
if enhanceTool.eq.GetValue()==False:
self.img.equalize(None)
if enhanceTool.sharp.GetValue()==True:
self.img.enhanceSharpness(2.0)
if enhanceTool.sharp.GetValue()==False:
self.img.enhanceSharpness(1.0)
if enhanceTool.invert.GetValue()==True:
self.img.invert(True)
if enhanceTool.invert.GetValue()==False:
self.img.invert(False)
self.img.load(self.currentImage)
imageBrowser.iWidth = self.img.wx().GetWidth()
imageBrowser.iHeight = self.img.wx().GetHeight()
self.img =
self.img.wx().Scale(imageBrowser.iWidth*Workspace.zoomScale,
imageBrowser.iHeight*Workspace.zoomScale)
self.ibrowserBitmap.SetBitmap(wx.BitmapFromImage(self.img))
self.bmpWidth, self.bmpHeight = self.ibrowserBitmap.GetSize()
self.Refresh()
self.Fit()
Finally, here is my OnPaint function:
def OnPaint(self, event):
paintDC = wx.PaintDC(self.browserPanel)
if self.GRIDSIZE != 0:
paintDC.SetBackgroundMode(wx.TRANSPARENT)
numRows, numCols = self.GRIDSIZE, self.GRIDSIZE
gridWid, gridHgt = paintDC.GetSizeTuple()
cellWid = float( gridWid - 1) / numRows
cellHgt = float( gridHgt - 1) / numCols
paintDC.SetBrush( wx.Brush( wx.BLACK, wx.TRANSPARENT) )
paintDC.SetPen( wx.Pen( wx.BLACK, 1, wx.SOLID) )
paintDC.DrawRectangle( 0, 0, gridWid, gridHgt )
for rowNum in xrange( numRows + 1) :
paintDC.DrawLine( 0, rowNum*cellHgt, gridWid,
rowNum*cellHgt )
for colNum in xrange( numCols + 1 ) :
paintDC.DrawLine( colNum*cellWid, 0, colNum*cellWid,
gridHgt )
event.Skip()
···
On Apr 13, 11:28 am, Cody Precord <codyprec...@gmail.com> wrote:
Hi,
On Wed, Apr 13, 2011 at 9:50 AM, PRobbins <pjrobbin...@gmail.com> wrote:
> Ok I have implemented your suggestions and I can see bits of the grid
> sticking out from behind the image now and whenever the image
> refreshes I can briefly see the grid flash on the screen before it is
> covered up by the image. Any idea what's going on? How can I make my
> image transparent and/or put the grid on top? Sorry if some of these
> questions are elementary, this is really the first time I've worked
> with images in wxPython before.Can't say without knowing what your doing.
Please make a runnable, small as possible sample
(MakingSampleApps - wxPyWiki) that demonstrates the
problem.I also attached a simple example that you can try out.
Regards,
Cody
paint.py
3KViewDownload
Hi,
My application is quite large so I'm not sure I can make a small
enough sample. Here is the relevant code from my program however:First I am creating a panel and putting a Static Bitmap on it:
Thats your problem then. The StaticBitmap is a separate window from
the one your drawing on. So your drawing on its parent and then the
StaticBitmap is getting displayed over it.
Draw the bitmap in the OnPaint handler instead of using a StaticBitmap
control. See the sample I attached to the previous message and replace
the DrawCircle code with DrawBitmap to draw your Bitmap instead.
Cody
···
On Wed, Apr 13, 2011 at 10:39 AM, PRobbins <pjrobbins89@gmail.com> wrote:
Ok, I think I understand where you're going. I'm still taking baby
steps with understanding how this works though. In my above code, I
create the static bitmap and then every time the user asks the program
to switch images, the bitmap is set to a new bitmap created from the
image self.img. If I'm understanding you correctly, you want me to
draw the new images bitmap in the OnPaint function, then draw the grid
lines over it, right?
···
On Apr 13, 11:52 am, Cody Precord <codyprec...@gmail.com> wrote:
Hi,
On Wed, Apr 13, 2011 at 10:39 AM, PRobbins <pjrobbin...@gmail.com> wrote:
> My application is quite large so I'm not sure I can make a small
> enough sample. Here is the relevant code from my program however:> First I am creating a panel and putting a Static Bitmap on it:
Thats your problem then. The StaticBitmap is a separate window from
the one your drawing on. So your drawing on its parent and then the
StaticBitmap is getting displayed over it.Draw the bitmap in the OnPaint handler instead of using a StaticBitmap
control. See the sample I attached to the previous message and replace
the DrawCircle code with DrawBitmap to draw your Bitmap instead.Cody
Hi,
···
On Wed, Apr 13, 2011 at 11:19 AM, PRobbins <pjrobbins89@gmail.com> wrote:
Ok, I think I understand where you're going. I'm still taking baby
steps with understanding how this works though. In my above code, I
create the static bitmap and then every time the user asks the program
to switch images, the bitmap is set to a new bitmap created from the
image self.img. If I'm understanding you correctly, you want me to
draw the new images bitmap in the OnPaint function, then draw the grid
lines over it, right?
Yes, I think you will find that to work much better for this type of task.
Cody
p.s) this group prefers bottom posting when replying to messages.
(Why is Bottom-posting better than Top-posting)
I've played around with this suggestion a little bit and haven't made
any worthwhile progress. I'm coming in and working on code that
someone else has written so my hands are tied a little bit as far as
restructuring it. I've poked around the forums and wxPython website/
code samples a bit more and I was wondering if I could solve my
problem by keeping the static bitmap and converting my image to a
bitmap, using a memory DC, drawing the gridlines on it and loading the
resulting bitmap into the static bitmap?
···
On Apr 13, 12:22 pm, Cody Precord <codyprec...@gmail.com> wrote:
Hi,
On Wed, Apr 13, 2011 at 11:19 AM, PRobbins <pjrobbin...@gmail.com> wrote:
> Ok, I think I understand where you're going. I'm still taking baby
> steps with understanding how this works though. In my above code, I
> create the static bitmap and then every time the user asks the program
> to switch images, the bitmap is set to a new bitmap created from the
> image self.img. If I'm understanding you correctly, you want me to
> draw the new images bitmap in the OnPaint function, then draw the grid
> lines over it, right?Yes, I think you will find that to work much better for this type of task.
Cody
p.s) this group prefers bottom posting when replying to messages.
(Why is Bottom-posting better than Top-posting)
The artifact you are seeing is very dependent on both the particular platform you are running as well as the processor speed. There are some not very well documented “ins and outs” to get clean redraws using DCs. Attached is from a thread I started concerning DC flicker prevention. It may or may not apply to your problem, but is typical of what kind of things you can try.
Ray
DC Fast Redraw Techniques.txt (2.98 KB)
Hi,
I've played around with this suggestion a little bit and haven't made
any worthwhile progress. I'm coming in and working on code that
someone else has written so my hands are tied a little bit as far as
restructuring it. I've poked around the forums and wxPython website/
code samples a bit more and I was wondering if I could solve my
problem by keeping the static bitmap and converting my image to a
bitmap, using a memory DC, drawing the gridlines on it and loading the
resulting bitmap into the static bitmap?
It adds some extra steps, but you can certainly do that too.
You would need to get rid of the OnPaint handling and add an method
that you would have to manually call when you change the grid layout
or image that is being displayed to update the StaticBitmap control
with a new Bitmap.
Pretty much been handed the code to do what you need to do already so
not sure what else you are stuck on at this point. Highly suggest
making a minimal sample app as mentioned before, as you there is a
good chance you would figure out what your doing wrong while writing
the sample.
Cody
···
On Wed, Apr 13, 2011 at 1:04 PM, PRobbins <pjrobbins89@gmail.com> wrote:
You had best not use a wx.StaticBitmap at all. All you need is a wx.Bitmap to do everything you want to do.The bitmap can be created directly from a graphic file.
Have you looked at either of the code examples ? Both draw grid lines over top a wx.Bitmap in the same way. They both work with a wx.Bitmap, not a wx.StaticBitmap. When a wx.PaintDC is created it’s wx.Bitmap is the bitmap of the interior (Client) of whatever window is the parameter to the PaintDC. Cody’s example uses the implicit bitmap from a wx.Panel while mine uses a wx.Bitmap created from a graphic (photo) file.
Ray
Great! Thanks for your help guys. I got everything working.
···
On Apr 14, 12:38 pm, Ray Pasco <pascor22...@gmail.com> wrote:
You had best not use a wx.StaticBitmap at all. All you need is a wx.Bitmap
to do everything you want to do.The bitmap can be created directly from a
graphic file.Have you looked at either of the code examples ? Both draw grid lines over
top a wx.Bitmap in the same way. They both work with a wx.Bitmap, *not a
wx.StaticBitmap*. When a wx.PaintDC is created it's wx.Bitmap is the bitmap
of the interior (Client) of whatever window is the parameter to the PaintDC.
Cody's example uses the implicit bitmap from a wx.Panel while mine uses a
wx.Bitmap created from a graphic (photo) file.Ray