title: Pixel information from bitmap or wxImage using wxPython
body: <p>I have a question concerning getting an individual pixel’s color information from a bitmap. I’ve searched these forums, along with demos and tutorials, and while I believe I understand what I need to do in theory, I’m not able to actually do it.</p>
  
  <p>Here’s an example of my code (I’ve shortened it, but this is a working example):</p>
  
  <pre><code>import os, sys
  import wx
  import wx.lib.plot as plot
  import Image
  
  class MyFrame(wx.Frame):
      def __init__(self, parent, id, title):
          wx.Frame.__init__(self, parent, id, title, size=(500, 500))
  
          HolderPanel = wx.Panel(self, wx.ID_ANY)
  
          panel2 = MyPanel_2(HolderPanel, wx.ID_ANY)
  
          framesizer = wx.BoxSizer(wx.HORIZONTAL)
          framesizer.Add(panel2, 1, wx.EXPAND | wx.BOTTOM | wx.TOP | wx.RIGHT, 2)
  
          HolderSizer = wx.BoxSizer(wx.VERTICAL)
          HolderSizer.Add(framesizer, 1, wx.EXPAND)
  
          HolderPanel.SetSizer(HolderSizer)
          self.Show()
  
  
  class MyPanel_2(wx.Panel):
  
      def __init__(self, parent, id):
          wx.Panel.__init__(self, parent, id, style=wx.SIMPLE_BORDER)
          self.SetBackgroundColour('grey')
  
  
          # Create main image holder
          self.img_1 = wx.EmptyImage(300,300)        
          self.imageCtrl_1 = wx.StaticBitmap(self, wx.ID_ANY, wx.BitmapFromImage(self.img_1)) # Starting with an EmptyBitmap, the real one will get put there by the call onView
          self.PhotoMaxSize_1 = (300)
          self.imageCtrl_1.Bind(wx.EVT_LEFT_DOWN, self.onMouseClick_img1)
  
          # Create the browse button
          brwsBtn = wx.Button(self, wx.ID_ANY, 'Browse', (10, 10))
          brwsBtn.Bind(wx.EVT_BUTTON, self.onBrowse)
  
          # Set up the text box
          self.photoTxt = wx.TextCtrl(self, size=(200,-1))
  
          # Create the sizers
          vsizer1 = wx.BoxSizer(wx.VERTICAL)
          hsizer3 = wx.BoxSizer(wx.HORIZONTAL)
          vsizer_MAIN = wx.BoxSizer(wx.VERTICAL)
  
          # -----------------------------------------------------------------------------------------------------------
          vsizer1.Add(self.imageCtrl_1, proportion = 0, flag= wx.ALIGN_CENTRE | wx.ALL, border=10)
  
          # -----------------------------------------------------------------------------------------------------------
          hsizer3.Add(brwsBtn, proportion = 0, flag = wx.ALIGN_CENTRE_VERTICAL | wx.LEFT | wx.RIGHT, border=10)
          hsizer3.Add(self.photoTxt, proportion = 1, flag = wx.ALIGN_CENTRE_VERTICAL | wx.LEFT | wx.RIGHT, border = 10)
  
          # -----------------------------------------------------------------------------------------------------------
          vsizer_MAIN.Add(vsizer1, proportion = 1, flag = wx.EXPAND)
          vsizer_MAIN.Add(hsizer3, proportion = 1, flag = wx.EXPAND)
  
          # -----------------------------------------------------------------------------------------------------------
          self.SetSizer(vsizer_MAIN)
  
      def onBrowse(self, event):
          """ 
          Browse for file
          """
          wildcard = "pictures (*.jpg, *.jpeg, *.png)|*.jpg;*.jpeg;*.png"
          dialog = wx.FileDialog(None, "Choose a file", wildcard=wildcard, style=wx.OPEN)
  
          if dialog.ShowModal() == wx.ID_OK:
              self.photoTxt.SetValue(dialog.GetPath())
          dialog.Destroy() 
          self.onView()
  
      def onView(self):
  
          self.filepath = self.photoTxt.GetValue()
  
          self.img_1 = wx.Image(self.filepath, wx.BITMAP_TYPE_ANY)
          # scale the image, preserving the aspect ratio
          W = self.img_1.GetWidth()
          H = self.img_1.GetHeight()
          if W &gt; H:
              NewW = self.PhotoMaxSize_1
              NewH = self.PhotoMaxSize_1 * H / W
          else:
              NewH = self.PhotoMaxSize_1
              NewW = self.PhotoMaxSize_1 * W / H
          self.img_1 = self.img_1.Scale(NewW,NewH)
  
          self.imageCtrl_1.SetBitmap(wx.BitmapFromImage(self.img_1)) # Converts the scaled image to a wx.Bitmap and put it on the wx.StaticBitmap
          self.Refresh()
  
      def onMouseClick_img1(self, event):
  
          im = Image.open(self.filepath)
          pos = event.GetPosition()
          pix = im.load()
          print pix[pos.x, pos.y]
  
  app = wx.App()
  MyFrame(None, -1, 'Current Build')
  app.MainLoop()
  </code></pre>
  
  <p>What this allows me to do is browse for and import an image, resize the image, and then select individual pixels to access their color information. However, there is a problem with this code: the color information does not match with the actual image (and in some cases, there’s an error relating to being out of the image’s range). I went back to check this and realized that</p>
  
  <pre><code>        im = Image.open(self.filepath)
  </code></pre>
  
  <p>is referencing the actual path to the image, and that’s what the <code>event.GetPosition()</code> is reading (since the resized image isn’t the same size, my code isn’t reading what’s presented). I realized that I can get the pixel's color information because I'm looking at a <code>wxImage</code> and not the converted bitmap from the original image. By adjusting the <code>onMouseClick_img1</code> event to just:</p>
  
  <pre><code>    def onMouseClick_img1(self, event):
  
          pos = event.GetPosition()
  
          print pos
  </code></pre>
  
  <p>I can read the position of any point on my empty StaticBitMap OR on my loaded, resized image that I converted to a bitmap. However, I cannot pull the color information of the selected pixel. After searching, I found <a href="https://groups.google.com/forum/?fromgroups=#!topic/wxpython-users/ncGKIAUh7Kk" rel="nofollow">this page</a> </p>
  
  <p>and tried both methods, but ended up with errors for both. Since I’d like to use the <code>wx.Image</code> method, I tried this:</p>
  
  <pre><code>    def onMouseClick_img1(self, event):
  
          img = wx.ImageFromBitmap(self.img_1)
  
          pos = event.GetPosition()
          print (img.GetRed(pos), img.GetGreen(pos), img.GetBlue(pos))
  </code></pre>
  
  <p>but I get this error message:</p>
  
  <blockquote>
    <p>Traceback (most recent call last):   File "/Users/Documents/[user
    name]/Eclipse_workspace/builder/src/GUI/Maybe.py", line 254, in
    onMouseClick_img1
        img = wx.ImageFromBitmap(self.img_1)   File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/wx/_core.py",
    line 3750, in ImageFromBitmap
        val = <em>core</em>.new_ImageFromBitmap(*args, **kwargs) TypeError: in method 'new_ImageFromBitmap', expected argument 1 of type 'wxBitmap
    const &amp;'</p>
  </blockquote>
  
  <p>I thought that all I needed to do was convert the bitmap back to an image once I had resized it and then pull the pixel information from that, but I'm obviously doing something incorrectly somewhere. Any help would be greatly appreciated. This is my first attempt at a real GUI, and I'm new to <code>wxPython</code>, so if you see something more general that's wrong, please feel free to let me know.</p>