Hi, i have a major issue in program and i cannot figure out why. It is an image stacker which averages, brightens, darkens multiple images to a single image.

When i call function self.saveFile() straight after the program has started, it acts as it should. I can specify a new filename to save an image to. Of course that is useless as there is no image to save.
If i call the same function once an image has been created i cannot specify a new filename and can only overwrite an existing one.

Could anybody give me any help?

Cheers

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import sys, Image, numpy, ImageQt
from PyQt4 import QtCore, QtGui
from stacker import Ui_stacker

class StartQt4(QtGui.QWidget):
    def __init__(self, parent=None):
	QtGui.QWidget.__init__(self, parent)
	self.ui = Ui_stacker()
	self.ui.setupUi(self)
	self.worked = 0
	self.ready = 0
	
	self.homePath = QtCore.QDir.homePath()
	
        QtCore.QObject.connect(self.ui.fileBut,QtCore.SIGNAL("clicked()"),self.getFiles)
	QtCore.QObject.connect(self.ui.saveBut,QtCore.SIGNAL("clicked()"),self.saveFile)
	QtCore.QObject.connect(self.ui.runBut,QtCore.SIGNAL("clicked()"),self._run)
	QtCore.QObject.connect(self.ui.zoomSpinBox, QtCore.SIGNAL("valueChanged(int)"), self.showimg)
	
    def resizeEvent(self, event):
	if self.worked == 1:
	    self.showimg()
	else:
	    print "Warning: No captures present"


    def getFiles(self):
	files = QtGui.QFileDialog.getOpenFileNames(self,"Select Images", self.homePath, ("Images (*.png *.tiff *.jpg)"))
	self.inFiles = []
	for fileName in files:
	    self.inFiles.append(unicode(fileName.replace(" ","\ ")))
	 
	self.checkFiles()
	    
    def checkFiles(self):
	self.im = []
	for n in range(len(self.inFiles)):
	    self.im.append(Image.open(self.inFiles[n]).convert("L"))
	
	for n in range(2,len(self.inFiles),1):
	    if (self.im[n].size[0] != self.im[1].size[0]) or (self.im[n].size[1] != self.im[1].size[1]):
		print "Shit!"
		# could do with closing opened images
		self.im = []
		break
	self.ready = 0
	
    def saveFile(self):
	saveFile = QtGui.QFileDialog.getSaveFileName()
	print saveFile
	saveFile = saveFile.replace(" ","\ ")
	saveFile = saveFile.replace("(","\(")
	saveFile = saveFile.replace(")","\)")
	print saveFile	
	self.im_z.save(saveFile)
	
## Everything from here on really needs to be shoved in a QThread
	
    def _run(self):
	if self.ui.aveRadBut.isChecked():
	    mode = "ave"
	    
	elif self.ui.brightRadBut.isChecked():
	    mode = "bri"
	
	elif self.ui.darkRadBut.isChecked():
	    mode = "dar"
	
	if self.ready == 0: 
	    print "not sorted"
	    self.im_ = []
		
	    for n in range(len(self.inFiles)):
		self.im_.append(numpy.asarray(self.im[n], dtype = float))
	    
	    self.im_z = numpy.zeros((self.im[1].size[1],self.im[1].size[0]), dtype = "uint8" ) 
	    self.ready = 1
	
	self.stack(mode)
	
    def stack(self,mode):
	print mode
	
	# scans left to right, top to bottom, and averages the pixel value at each location
	if mode == "ave":
	    for y in range(self.im[1].size[1]):
		    for x in range(self.im[1].size[0]):
			val = 0.0
			for z in range(len(self.inFiles)):
			    val = val + self.im_[z][y,x]
			self.im_z[y,x] = val / len(self.inFiles)
			
	if mode == "bri":
	    for y in range(self.im[1].size[1]):
		    for x in range(self.im[1].size[0]):
			val = []
			for z in range(len(self.inFiles)):
			    val.append(self.im_[z][y,x])
			self.im_z[y,x] = max(val)
			
	if mode == "dar":
	    for y in range(self.im[1].size[1]):
		    for x in range(self.im[1].size[0]):
			val = []
			for z in range(len(self.inFiles)):
			    val.append(self.im_[z][y,x])
			self.im_z[y,x] = min(val)
			
	self.im_z = Image.fromarray(self.im_z)
	self.worked = 1
	self.showimg()
	 
    def showimg(self):
	if self.worked == 1:
	    percent = self.ui.zoomSpinBox.value()
	    factor = percent / 100.0
	    image = ImageQt.ImageQt(self.im_z)
	    width = self.ui.imageLabel.width() * factor
	    height = self.ui.imageLabel.height() * factor
	    image = image.scaled(width, height, QtCore.Qt.KeepAspectRatio)
	    self.ui.imageLabel.setPixmap(QtGui.QPixmap.fromImage(image))
	else:
	    print "No image present"
	    	
	    
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQt4()
    myapp.show()
    sys.exit(app.exec_())

Your question is too vague to answer. What does "cannot specify a new filename and can only overwrite an existing one" mean? Are there errors? If so what are they? The saveFile function would be the first place to look. What does "print saveFile" display? Also, it is bad form to have function names the same as variable names.

The next thing I looked at was "self.im_z.save(saveFile)" to see what ".save" did. I found
self.im_z = numpy.zeros((self.im[1].size[1],self.im[1].size[0]), dtype = "uint8" )
self.im_z[y,x] = val / len(self.inFiles)
self.im_z = Image.fromarray(self.im_z)
None of these statements appear to have a "save" method. More duplicate names? There is no way to tell, so all I can suggest is to add some print statements to self.im_z.save(saveFile), where ever it is, so you can see if it is being called. In the following code snippet, the second "test_function()" should give an error something like "int is not callable" because of duplicate names.

def test_function():
   print "test function"

test_function()
test_function=1
test_function()

"self.im_z.save(saveFile)"

is a standard Python Imaging Library function. You are saving the PIL object (created in the "self.im_z = numpy.zeros....." section you mention) "self.im_z" to the a file "saveFile"

I didn't know that having variables and functions share the same name is bad so cheers for that. I'll try and sort that out soon and see if that helps.

"cannot specify a new filename and can only overwrite an existing one"
By this i mean that when i a FileDialog appears, the filename textedit entry at the bottom of it cannot be used to create a new filename to save the PIL object to. The "save" button is grayed out and inactive until a filename, which already exists in the local directory, is selected. However, this is not the default action of QtGui.getSaveFileName(). This unexpected occurence happens after the PIL object has been created.

I hope that clears up some poor wording made by myself earlier.

This article has been dead for over six months. Start a new discussion instead.