loading a DDS file into a QImage for display in PyQt

402 views
Skip to first unread message

Benjam901

unread,
Aug 17, 2015, 9:26:49 AM8/17/15
to Python Programming for Autodesk Maya
Hello all,

I am having some trouble loading a dds file into PyQt for displaying in a window. 

I have dug around and I keep being pointed towards OpenGL.GL and QtOpenGL. I found a function on tech artists forum http://tech-artists.org/forum/showthread.php?5196-Simple-DDS-loader that supposedly returns a Qimage from a dds filepath but when the function tries to bind the texture it fails instantly or returns 0. Am I missing a step before trying to bind the image?

I have also tried a custom fucntion earlier using QtOpenGL but I have had no luck so far

There doesn't seem to be a huge amount of info out there on this so hopefully someone on here can help shine a light!

The code is below to ilustrate my issue:

import os
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtOpenGL import *
from OpenGL.GL import *
class ShaderCoordWindow(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self)
global coordWindow
coordWindow = QtGui.QDialog()
coordWindow.resize(512, 512)
coordWindow.setWindowTitle("Objects to skin")
coordWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
testDDS = r'D:\\test.dds'
testJPG = r'D:\\test_jpg.jpg'
jpgPixMap = QtGui.QPixmap(testJPG)
qFileDDS = fileDDS(testDDS)
testImg = QtGui.QPixmap.fromImage(qFileDDS._qImage)
imageLabel = QtGui.QLabel(coordWindow)
imageLabel.setPixmap(testImg)
layout = QtGui.QHBoxLayout()
layout.addWidget(imageLabel)
coordWindow.setLayout(layout)
coordWindow.show()
###########################################################################
## DDS file reader
class fileDDS(object):
"""This class represnts a generic DDS file as a QImage"""
#global gDebug
# --BASE-METHODS-------------------------------------------------------
# --constructor-
def __init__(self, filePath=None):
self._filePath = None
self._width = int(0)
self._height = int(0)
self._qImage = None
if filePath != None:
self._filePath = filePath
self._qImage = self.readDDSFile(self._filePath)
# --method-------------------------------------------------------------
def readDDSFile(self, filePath=None):
print 'reading', filePath
glWidget = QGLWidget()
glWidget.makeCurrent()
texture = glWidget.bindTexture(QtCore.QString(filePath))
if not texture:
print 'not textures'
return QtGui.QImage()
# Determine the size of the DDS image
glBindTexture(GL_TEXTURE_2D, texture)
self._width = glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH)
self._height = glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT)
if self._width == 0 and self._height == 0:
print 'width and height nothing'
return QtGui.QImage()
pbuffer = QGLPixelBuffer(QtCore.QSize(self._width, self._height), glWidget.format())
if not pbuffer.makeCurrent():
print 'no pbuffer'
return QtGui.QImage()
pbuffer.drawTexture(QtCore.QRectF(-1, -1, 2, 2), texture)
return pbuffer.toImage()
def run():
app = QtGui.QApplication(sys.argv)
ShaderCoordWindow()
sys.exit(app.exec_())
run()

Benjam901

unread,
Aug 17, 2015, 12:06:36 PM8/17/15
to Python Programming for Autodesk Maya
UPDATE:
I shortened the function for readibility but I am still displaying nothing but blank on my qt window. My IDE prompts me that I am missing a QImage on this line QtGui.QPixmap.fromImage(img)which is odd sicne I am passing something into it and calling it straight from QtGui Module. I can't help but think I am missing something?

def returnPixMap(self, ddsPath):
glWidget = QGLWidget()
glWidget.makeCurrent()
texture = glWidget.bindTexture(ddsPath)
width = -1
height = -1
glBindTexture(GL_TEXTURE_2D, texture)
width = glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH)
height = glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT)
pbuffer = QGLPixelBuffer(QtCore.QSize(width, height), glWidget.format())
pbuffer.drawTexture(QtCore.QRectF(-1, -1, 2, 2), texture)
img = pbuffer.toImage()
return QtGui.QPixmap.fromImage(img)
...

damon shelton

unread,
Aug 17, 2015, 2:24:52 PM8/17/15
to python_in...@googlegroups.com
try this
QtGui.QPixmap.fromImage(QtGui.QImage(img))
see if it fixes your issue.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/90a1aabd-9a1a-47eb-9f62-6232239bd454%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ben Hearn

unread,
Aug 18, 2015, 3:37:10 AM8/18/15
to python_in...@googlegroups.com
Hello Damon,

No dice on that one I am afraid. img is already a QImage since I got it from pbuffer.toImage() I have implemented it however but no luck. I am going to try and run a conversion under the hood and if it isn't too slow speed wise I may stick with that solution. I would very much like to be able to manipulate DDS image data though, have you managed to solve something like this before?

-- Ben

--
You received this message because you are subscribed to a topic in the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python_inside_maya/s1BKlrcJ9vI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAM9RXoJag%2B55v28u7KW88eZzjm4ofW9yB3wobX5_HOfXbJ7Uqw%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--

Tel - +46 76245 92 90 (Sweden)

Benjam901

unread,
Aug 20, 2015, 9:53:58 AM8/20/15
to Python Programming for Autodesk Maya
[SOLVED]

Hello all,

I have found a way to display this and I have posted the solution below.

Unfortunately I did not find a way to actually display the DDS file so I had to run a convert under the hood using Image Magick (great tool).

I then ran the TGA file image through the rungs of formatting the data to generate a pixmap.

Anyway here are the functions I used to help my situation. I hope it helps some people!!

CODE:

def convertDDS(self, ddsPath='', imageMagickDir='', overlay=False):
	""" Convert the DDS files passed in to a tga file """
	convert = imageMagickDir+'\\convert'
	if overlay:
		tempOutPath = r'D:\\magickOverlayOut.tga'
	else:
		tempOutPath = r'D:\\magickOut.tga'
	subprocess.call([convert, ddsPath, tempOutPath])
	return tempOutPath

def returnQPixmapFromImage(self, inputPath='', overlayPath=''):
	# We turn out input paths into ImageQt objects for Qt to use later
	inImg = Image.open(inputPath)
	inputImg = ImageQt.ImageQt(inImg)
	overImg = Image.open(overlayPath)
	overlayImage = ImageQt.ImageQt(overImg)

	# Creating the input image into a QPixmap
	pix = QtGui.QPixmap.fromImage(inputImg)
	pix = pix.scaled(512, 512, QtCore.Qt.KeepAspectRatioByExpanding)
	pixHeight = round(pix.size().height(), 2)
	pixWidth = round(pix.size().width(), 2)

	# Creating the overlay images
	overlayPix = QtGui.QPixmap.fromImage(overlayImage)
	overlayImage = QtGui.QPixmap.toImage(overlayPix)
	overlayImage = overlayImage.scaled(pix.size(), QtCore.Qt.KeepAspectRatio)

	# Check the image has an alpha channel so we can remove it for preview
	if pix.hasAlpha():
		qtFormat = QtGui.QImage.Format_RGB32
	else:
		# We need this for DXT1's/TGA's without an alpha. For some reason it crashes the app
		qtFormat = QtGui.QImage.Format_ARGB32

	# Converting to QImage and removing the alpha then back to pixmap again
	stripAlpha = QtGui.QPixmap.toImage(pix).convertToFormat(qtFormat)
	myQImg = stripAlpha

	painter = QtGui.QPainter()
	painter.begin(myQImg)
	painter.drawImage(0, 0, overlayImage)
	painter.end()

	finalImage = QtGui.QPixmap.fromImage(myQImg)

	return finalImage, pixHeight, pixWidth


On Monday, 17 August 2015 15:26:49 UTC+2, Benjam901 wrote:
...
Reply all
Reply to author
Forward
0 new messages