`
schi
  • 浏览: 203858 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

display an image with pyopengl and Pillow

阅读更多
使用opengl和Pillow来显示图片。
如果你以前使用过python来处理图片的话,那你对PIL有一定的了解,PIL是python的一个第3方库,主要是用来做图片处理的,但从1.1.7版本开始就已经停止维护了。
而Pillow则是PIL的衍生分支,它支持PIL的API,使用方法都一样,到现在还在维护。

首先我们来创建一个QGLWidget
class MyGLWidget(QGLWidget):

添加一些buffer(内存)对象
# buffer object ids
self.vaoID = None
self.vboVerticesID = None
self.vboIndicesID = None
self.textureID = None

self.sprogram = None

使用Pillow来加载图片
# chang this to load your image file
self.loadImage('Lenna.png')

然后我们重写initializeGL方法来进行初始化
def initializeGL(self):

创建并编译shader
# create shader from file
vshader = shaderFromFile(GL_VERTEX_SHADER, 'shader.vert')
fshader = shaderFromFile(GL_FRAGMENT_SHADER, 'shader.frag')
# compile shaders
self.sprogram = shaders.compileProgram(vshader, fshader)

设置shader里的一些参数
# get attribute and set uniform for shaders
glUseProgram(self.sprogram)
self.vertexAL = glGetAttribLocation(self.sprogram, 'pos')
self.tmUL = glGetUniformLocation(self.sprogram, 'textureMap')
glUniform1i(self.tmUL, 0)
glUseProgram(0)

设置平面的坐标和顶点循序
# two triangle to make a quad
self.vertices = np.array((0.0, 0.0, 
                          1.0, 0.1, 
                          1.0, 0.9, 
                          0.0, 1.0), dtype=np.float32)
self.indices = np.array((0, 1, 2, 
                         0, 2, 3), dtype=np.ushort)



然后将数据传送到显卡
# set up vertex array
self.vaoID = glGenVertexArrays(1)
self.vboVerticesID = glGenBuffers(1)
self.vboIndicesID = glGenBuffers(1)

glBindVertexArray(self.vaoID)
glBindBuffer(GL_ARRAY_BUFFER, self.vboVerticesID)
# copy vertices data from memery to gpu memery
glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
# tell opengl how to procces the vertices data
glEnableVertexAttribArray(self.vertexAL)
glVertexAttribPointer(self.vertexAL, 2, GL_FLOAT, GL_FALSE, 0, None)
# send the indice data too
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vboIndicesID)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.indices.nbytes, self.indices, GL_STATIC_DRAW)

在我们传送图片数据到显卡之前,我们需要从上向下反转图片,不然我们显示的图片就是上向下反转的图片
# flip the image in the Y axis
im = self.im.transpose(Image.FLIP_TOP_BOTTOM)

然后传送图片数据到显卡
# set up texture
self.textureID = glGenTextures(1)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.textureID)
# set filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
# set uv coords mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
# send the image data to gpu memery
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.im.size[0], self.im.size[1], 
             0, GL_RGB, GL_UNSIGNED_BYTE, im.tostring())

这里你可以吧uv的坐标模式换一下
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)

并把shader.vert里的uv坐标改成
uv = pos*2 - 1;

你将会得到



到这里我们就可以开始进行渲染绘制了
def paintGL(self, *args, **kwargs):
    # clear the buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
    # active shader
    glUseProgram(self.sprogram)
    # draw triangles
    glDrawElements(GL_TRIANGLES, self.indices.size, GL_UNSIGNED_SHORT, None)
    glUseProgram(0)

至于shader.vert和shader.frag,做的都是非常简单的事情
shader.vert负责接收顶点信息,并保存uv的坐标,最后把uv传递给shader.frag,然后它通过uv坐标来读取图片的像素并导出给硬件,最终硬件进行显示。




完整的代码可以从这里获取
https://github.com/mackst/opengl-samples/tree/master/displayImage

ps.图片需要你们自己添加
  • 大小: 832.9 KB
  • 大小: 10.5 KB
  • 大小: 739.9 KB
分享到:
评论
1 楼 schi 2014-04-09  
相对Pillow和PySide而言,显示图片opengl就显得太繁重了,opengl需要100多行的代码,而它们都非常简单
from PIL import Image
im = Image.open("Lenna.jpg")
im.show()

import sys
from PySide.QtCore import *
from PySide.QtGui import *

app = QApplication(sys.argv)
im = QPixmap("Lenna.jpg")
label = QLabel()
label.setPixmap(im)
label.show()
sys.exit(app.exec_())


但如果你需要做图片处理的话,opengl的优势就体现出来了,例如要实现[ur=]http://schi.iteye.com/blog/1826850]convert color image to grayscale with pyopencl(example code) [/url]
我们可以直接修改shader.frag成
void main()
{
    vec3 color = texture(textureMap, uv).rgb;
    float luminance = 0.2126f * color.x + 0.7152f * color.y + 0.0722f * color.z;
    outColor = vec4(luminance, luminance, luminance, 1.);
}

相关推荐

    wxPython and PyOpengl源码

    【源码分析】:wxPython and PyOpenGL Example.py 这个源文件可能包含以下关键部分: 1. **导入模块**:首先会导入必要的库,如wxPython的wx模块和PyOpenGL的gl和glu模块。 2. **定义类**:定义一个自定义的...

    PyOpenGL、PyOpenGL-accelerate的whl安装文件

    **PyOpenGL与PyOpenGL-accelerate** PyOpenGL是Python编程语言中的一个图形库,它提供了对OpenGL图形API的全面访问,使得Python程序员可以利用OpenGL的强大功能进行2D和3D图形编程。OpenGL是一个跨语言、跨平台的...

    Python GUI Programming Cookbook

    《Python GUI Programming Cookbook》是一本专注于使用Python进行图形用户界面编程的实用指南。这本书主要针对的是使用Python标准库中的tkinter模块来构建GUI应用程序的开发者。tkinter是Python内置的GUI库,它允许...

    Packt.Hands-On.GPU.Computing.with.Python.1789341078.epub

    Explore GPU-enabled programmable environment for machine learning, scientific applications, and gaming using PuCUDA, PyOpenGL, and Anaconda Accelerate Key Features Understand effective ...

    PyOpenGL-3.1.5-cp27-cp27m-win_amd64.zip

    《PyOpenGL-3.1.5在Windows x64系统的安装与应用详解》 PyOpenGL是Python编程语言中用于交互式处理OpenGL图形库的一个模块,它提供了与OpenGL标准接口的全面绑定,允许开发者在Python环境中创建复杂的3D图形。本文...

    pyopengl简单教程.zip

    PyOpenGL是Python编程语言中用于访问OpenGL图形库的接口,它允许开发者在Python环境中创建高性能的3D图形。OpenGL是一个跨平台的API,用于渲染2D、3D矢量图形,广泛应用于游戏开发、科学可视化以及工程应用等领域。...

    pyopengl windows x64 whl安装包

    pyopengl windows x64 whl安装包 本资源提供了python3.9和3.10版本,x64位安装包。 官方的下载地址已经失效 http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl

    PyOpenGL(-accelerate)-3.1.7-cp311-cp311-win-amd64.whl 下载

    pyopenGL

    pyopengl & demos -3.0.0b5

    《PyOpenGL与Demo应用探索——基于3.0.0b5版本》 PyOpenGL是Python编程语言中的一个OpenGL接口库,它为Python程序员提供了一种简单而强大的方式来利用OpenGL的强大功能。OpenGL是一种广泛用于图形处理的跨语言、跨...

    pyopengl.rar

    python pyopengl 64 位的包 64位系统必须使用64位的

    PyOpenGL-3.1.6-cp311-cp311-win_amd64.zip

    《PyOpenGL在Windows x64系统中的应用与安装详解》 PyOpenGL是Python语言与OpenGL图形库交互的重要接口,它提供了全面的OpenGL功能,让Python程序员可以方便地进行图形渲染和处理工作。版本3.1.6是针对Python 3.11...

    PyOpenGL-3.1.5-cp37-cp37m-win_amd64.whl

    解决:OpenGL.error.NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutI 下载后,在该目录打开cmd,安装pip install PyOpenGL-3.1.5-cp37-cp37m-win_amd64.whl

    PyOpenGL安装包3.0.1版本

    **PyOpenGL 3.0.1 安装包详解** PyOpenGL是Python编程语言中用于交互式图形处理的重要库,它提供了对OpenGL图形库的全面访问。OpenGL是一种跨平台的编程接口,允许开发者创建高性能的2D和3D图形。在Python环境中,...

    pyopengl-jtyy

    标题“pyopengl-jtyy”暗示我们关注的是Python中的PyOpenGL库,这是一个用于与OpenGL交互的Python绑定。OpenGL是一个跨语言、跨平台的应用程序编程接口(API),它用于渲染2D、3D图像,广泛应用于游戏开发、科学可视...

    PyOpenGL-3.1.6-cp310-cp310-win_amd64.zip

    《PyOpenGL-3.1.6在Windows x64系统中的安装与应用详解》 PyOpenGL是Python编程语言中用于与OpenGL交互的库,它为Python程序员提供了与OpenGL标准兼容的接口,使得开发者可以在Python环境下进行图形处理和3D渲染。...

    PyOpenGL-3.1.6-cp38-cp38-win_amd64.zip

    《PyOpenGL在Windows x64系统中的应用与安装详解》 PyOpenGL是Python的一个扩展库,它为Python程序员提供了一个接口来使用OpenGL图形库。OpenGL是一个跨语言、跨平台的编程接口,用于渲染2D、3D矢量图形,广泛应用...

    PyOpenGL-3.0.1a2.win32.exe PyopenGL

    PyOpenGL-3.0.1a2.win32.exe, python openGL库 for windows

    PyOpenGL-3.1.5-cp36-cp36m-win_amd64.whl.zip

    《PyOpenGL-3.1.5-cp36-cp36m-win_amd64.whl.zip:Python图形编程的基石》 在信息技术领域,Python作为一种强大的编程语言,广泛应用于各种场景,其中包括图形用户界面(GUI)和图形处理。PyOpenGL是Python中的一个...

    pyopengl testcode demo

    pyopengl testcode demopyopengl testcode demopyopengl testcode demopyopengl testcode demopyopengl testcode demo

    PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl.zip

    标题中的"PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl.zip"表明这是一个Python库PyOpenGL的特定版本(3.1.6)的安装包,用于AMD64(即64位)Windows系统。"cp311"暗示它兼容Python 3.11版本。".whl"是Python的 Wheel ...

Global site tag (gtag.js) - Google Analytics