我有一个关于从位图获取单个像素的颜色信息的问题。我搜索了这些论坛,以及演示和教程,虽然我相信我理解我理论上需要做什么,但我无法真正做到。位图或wxImage使用wxPython的像素信息
这里是我的代码(我已经缩短了,但是这是一个工作示例)的例子:
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 > 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()
这是什么让我做的是浏览并导入图片,调整图片的大小,然后选择单个像素来访问它们的颜色信息。但是,此代码存在问题:颜色信息与实际图像不匹配(并且在某些情况下,与超出图像范围有关的错误)。我回去检查并意识到
im = Image.open(self.filepath)
被引用到图像的实际路径,这就是event.GetPosition()
正在读什么(因为调整图像大小都不一样,我的代码不读书什么是呈现)。我意识到我可以获取像素的颜色信息,因为我正在查看wxImage
而不是从原始图像转换后的位图。通过调整onMouseClick_img1
事件只是:
def onMouseClick_img1(self, event):
pos = event.GetPosition()
print pos
我能读懂我的空StaticBitMap或我装,调整后的图像,我转换为位图的任何点的位置。但是,我无法拉取所选像素的颜色信息。搜索后,我发现this page
并尝试这两种方法,但结束了两个错误。因为我想用wx.Image
方法,我尝试这样做:
def onMouseClick_img1(self, event):
img = wx.ImageFromBitmap(self.img_1)
pos = event.GetPosition()
print (img.GetRed(pos), img.GetGreen(pos), img.GetBlue(pos))
但我收到此错误信息:
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 = core.new_ImageFromBitmap(*args, **kwargs) TypeError: in method 'new_ImageFromBitmap', expected argument 1 of type 'wxBitmap const &'
我认为所有我需要做的是转换位图回一旦我调整了图像的大小,然后从中提取像素信息,但我显然在某处做了不正确的事情。任何帮助将不胜感激。这是我第一次尝试一个真正的GUI,我是wxPython
的新手,所以如果你看到一些更一般的错误,请随时告诉我。
如果您可以将解决方案内容解决出来,并通过解决方案创建您自己的答案,那将更具可读性。因为这个问题现在这么长,所以很难解决这个问题。 – demongolem
我完全同意。当我第一次发布这篇文章时,我认为我需要一定的评分才能回答我自己的问题(因为这是我的第一篇文章,所以我没有这个问题)。总之,情况并非如此,所以我修正了它。 – user1759566