Re: Printing Matplotlib (MPL) Graphs in PIL?
Kevin Cazabon <[email protected]>
| Newsgroups | gmane.comp.python.image |
|---|---|
| Message-ID | <[email protected]> |
Here's a module that will print any PIL image for you... it's been a long time since I've modified it or tested it, but it should work on Windows systems at least. It was based on some code from someone else (I think I referenced them in the code), but cleaned up and expanded. There's some sample usages at the bottom I believe too. ImagePrintWin.py is what you want... I've included some random test files too. Good luck! It also includes a Tkinter class for a "Print" dialog, including print preview. (I'll gladly append more open licensing if anyone wants it, or if Fred is willing to add yet another hack of mine to the standard Library... sorry this one isn't so clean) Kevin. On 17 Jan 2010, at 11:16, Wayne Watson wrote: > I've used MPL a bit, and am wondering if there's a facility in PIL for sending graphic images to a printer, or putting them in some format like png? I don't necessarily want the graphics to appear in a window, but would like to print them directly once they are ready. Can one put in a page feed, so that images don't all fall on the same page or cut across pages? > > I asked about this in the MPL list and didn't get a single reply, so I guess there's nothing in MPL that will do it. > > > -- > Wayne Watson (Watson Adventures, Prop., Nevada City, CA) > > (121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time) > Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet > > "I was thinking about how people seem to read the Bible > a whole lot more as they get older; then it dawned on > me . . they're cramming for their final exam." > -- George Carlin > > Web Page: <www.speckledwithstars.net/> > > > _______________________________________________ > Image-SIG maillist - [email protected] > http://mail.python.org/mailman/listinfo/image-sig _______________________________________________ Image-SIG maillist - [email protected] http://mail.python.org/mailman/listinfo/image-sig
ImagePrintWin.py
(text/x-python-script, 100.4 KB) - not displayed
printdemo.py
(text/x-python-script, 7.4 KB)
# Demo of printing an image (requires PIL) # by Roger Burnham ([email protected]) import win32ui import win32con import afxres import Image import ImageWin import copy import string from pywin.mfc import docview from pywin.mfc import dialog PRINTDLGORD = 1538 IDC_PRINT_MAG_EDIT = 1010 class PrintView(docview.ScrollView): def __init__(self, doc): docview.ScrollView.__init__(self, doc) self.doc = doc self.image = self.pilDisplay = None dlg = win32ui.CreateFileDialog(1, None, None, (win32con.OFN_FILEMUSTEXIST| win32con.OFN_EXPLORER), 'Image File (*.bmp)|*.bmp||') dlg.SetOFNTitle('Image to Print') if dlg.DoModal() == win32con.IDOK: image = dlg.GetPathNames()[0] else: return image = Image.open(image) self.image = image.convert('RGB') self.image.filename = image.filename def OnInitialUpdate(self): self._obj_.OnInitialUpdate() if self.image is None: return self.pilDisplay = ImageWin.Dib(self.image.mode, self.image.size) self.pilDisplay.paste(self.image) self.SetScrollSizes(win32con.MM_TEXT, self.image.size) self.ResizeParentToFit(0) self.HookCommand(self.OnFilePrint, afxres.ID_FILE_PRINT) self.HookCommand(self.OnFilePrintPreview, win32ui.ID_FILE_PRINT_PREVIEW) def OnAttachedObjectDeath(self): docview.ScrollView.OnAttachedObjectDeath(self) def OnDraw(self, dc): if self.pilDisplay is not None: self.pilDisplay.expose(dc.GetHandleOutput()) def OnFilePrintPreview(self, *arg): self._obj_.OnFilePrintPreview() def OnFilePrint(self, *arg): self._obj_.OnFilePrint() def OnPreparePrinting(self, pInfo): flags = (win32ui.PD_USEDEVMODECOPIES| win32ui.PD_PAGENUMS| win32ui.PD_NOPAGENUMS| win32ui.PD_NOSELECTION) self.prtDlg = ImagePrintDialog(pInfo, PRINTDLGORD, flags) pInfo.SetPrintDialog(self.prtDlg) self._continuePrinting = 1 self.noteLines = [] self.printTop = 0 return self.DoPreparePrinting(pInfo) def OnBeginPrinting(self, dc, pInfo): mag = self.prtDlg['mag'] dc.SetMapMode(win32con.MM_ANISOTROPIC); dc.SetWindowOrg((0, 0)) dc.SetWindowExt((1, 1)) dc.SetViewportOrg((0, 0)) dc.SetViewportExt((mag, mag)) pInfo.SetFromPage(1) pInfo.SetToPage(100) def OnPrepareDC(self, dc, pInfo): if dc.IsPrinting(): mag = self.prtDlg['mag'] dc.SetMapMode(win32con.MM_ANISOTROPIC); dc.SetWindowOrg((0, 0)) dc.SetWindowExt((1, 1)) dc.SetViewportOrg((0, 0)) dc.SetViewportExt((mag, mag)) pInfo.SetContinuePrinting(self._continuePrinting) def OnPrint(self, dc, pInfo): page = pInfo.GetCurPage() metrics = dc.GetTextMetrics() cxChar = metrics['tmAveCharWidth'] cyChar = metrics['tmHeight'] left, top, right, bottom = pInfo.GetDraw() rect = self.ScreenToClient(self.GetWindowRect()) height = (rect[3]-rect[1]) if page == 1: if self.image.filename is not None: dc.TextOut(0, 2*cyChar, '%s - Page %d' % (self.image.filename, page)) top = top + (7*cyChar)/2 dc.MoveTo(left, top) dc.LineTo(right, top) top = top + cyChar pInfo.SetDraw((left, top, right, bottom)) left, top, right, bottom = pInfo.GetDraw() dc.SetWindowOrg((left, -top)) self.OnDraw(dc) dc.SetTextAlign(win32con.TA_LEFT|win32con.TA_BOTTOM) self.printTop = top+height+cyChar dc.SetWindowOrg((left, -self.printTop)) dc.MoveTo(left, 0) dc.LineTo(right, 0) self.noteLines.append(self.doc.GetTitle()) keys = self.image.info.keys() keys.sort() maxKey = 0 for key in keys: maxKey = max(maxKey, len(key)) for key in keys: val = self.image.info[key] if type(val) != type(''): val = `val` self.noteLines.append('%*s : %s' % (maxKey, key, val)) left, top, right, bottom = pInfo.GetDraw() self.noteLines.append('Notes:') for line in string.split(self.prtDlg['notes'], '\n'): if line: txtLine = None for word in string.split(line): if txtLine is None: tstLine = txtLine = ' ' + word else: tstLine = txtLine + ' ' + word w,h = dc.GetTextExtent(tstLine) if w <= right: txtLine = tstLine else: self.noteLines.append(txtLine) txtLine = ' ' + word self.noteLines.append(txtLine) lines = copy.copy(self.noteLines) if page > 1: if self.image.filename is not None: dc.TextOut(0, 2*cyChar, '%s - Page %d' % (self.image.filename, page)) self.printTop = self.printTop + (7*cyChar)/2 dc.MoveTo(left, self.printTop) dc.LineTo(right, self.printTop) else: self.printTop = self.printTop + cyChar/2 dc.SetWindowOrg((left, -self.printTop)) for line in lines: self.printTop = self.printTop + cyChar if self.printTop >= bottom: break dc.SetWindowOrg((left, -self.printTop)) dc.TextOut(0, 0, line) self.noteLines.remove(line) self._continuePrinting = (len(self.noteLines) > 0) if self._continuePrinting: self.printTop = 0 def OnEndPrinting(self, dc, pInfo): del self.prtDlg return self._obj_.OnEndPrinting(dc, pInfo) class ImagePrintDialog(dialog.PrintDialog): def __init__(self, pInfo, dlgID, flags=win32ui.PD_USEDEVMODECOPIES): dialog.PrintDialog.__init__(self, pInfo, dlgID, flags=flags) self['mag'] = 3 self['notes'] = ''' line 1 of some notes. line 2 of more notes. ''' def OnInitDialog(self): rc = dialog.PrintDialog.OnInitDialog(self) self.magCtl = self.GetDlgItem(IDC_PRINT_MAG_EDIT) self.magCtl.SetWindowText(`self['mag']`) return rc def OnOK(self): dialog.PrintDialog.OnOK(self) try: self['mag'] = string.atoi(self.magCtl.GetWindowText()) except: pass def Printdemo(): template = docview.DocTemplate(win32ui.IDR_PYTHONTYPE, None, None, PrintView) doc = template.OpenDocumentFile(None) doc.SetTitle ('Print Demo') PrintView(doc) template.close() if __name__=='__main__': import demoutils if demoutils.NeedGoodGUI(): Printdemo()
PrinterTesting.py
(text/x-python-script, 1.6 KB)
import win32ui
import win32gui
import win32con
import win32print
from PIL import Image, ImageWin
#
# Constants for GetDeviceCaps
HORZSIZE = 4
VERTSIZE = 6
HORZRES = 8 #Total device units horiz in page size
VERTRES = 10 #Total device units vert in page size
ASPECTX = 40
ASPECTY = 42
ASPECTXY = 44
PHYSICALWIDTH = 110 #
PHYSICALHEIGHT = 111
PHYSICALOFFSETX = 112
PHYSICALOFFSETY = 113
LOGPIXELSX = 88 #Device units per inch
LOGPIXELSY = 90 #Device units per inch
#
# Find the printer resolution to scale to
#
hDC = win32ui.CreateDC ()
hDC.CreatePrinterDC ("QMS-PS 2000 v52.4") # can optionally put a printer name in here
print "HORZSIZE:\t%s" %hDC.GetDeviceCaps (HORZSIZE)
print "VERTSIZE:\t%s" %hDC.GetDeviceCaps (VERTSIZE)
print "HORZRES:\t%s" %hDC.GetDeviceCaps (HORZRES)
print "VERTRES:\t%s" %hDC.GetDeviceCaps (VERTRES)
print "PHYSICALWIDTH:\t%s" %hDC.GetDeviceCaps (PHYSICALWIDTH)
print "PHYSICALHEIGHT:\t%s" %hDC.GetDeviceCaps (PHYSICALHEIGHT)
print "PHYSICALOFFSETX:\t%s" %hDC.GetDeviceCaps (PHYSICALOFFSETX)
print "PHYSICALOFFSETY:\t%s" %hDC.GetDeviceCaps (PHYSICALOFFSETY)
print "LOGPIXELSX:\t%s" %hDC.GetDeviceCaps (LOGPIXELSX)
print "LOGPIXELSY:\t%s" %hDC.GetDeviceCaps (LOGPIXELSY)
print "ASPECTX:\t%s" %hDC.GetDeviceCaps (ASPECTX)
print "ASPECTY:\t%s" %hDC.GetDeviceCaps (ASPECTY)
print "ASPECTXY:\t%s" %hDC.GetDeviceCaps (ASPECTXY)
print win32print.EnumPrinters(2)
#((8388608, 'QMS-PS 2000 v52.4,QMS-PS 2000 v52.4,', 'QMS-PS 2000 v52.4', ''), (8388608, 'Lexmark,Lexmark Z25-Z35,', 'Lexmark', ''))
#[x][2] is printer name
printTest.py
(text/x-python-script, 1.1 KB)
import ImageWin
import win32print
import win32ui
import Image
def printIm(img):
img.load()
dib=ImageWin.Dib('RGB',img.size)
dib.paste(img,None)
# get the default printer
pname = win32print.GetDefaultPrinter()
# get DC
try:
hnum=win32print.OpenPrinter(pname)
except:
print 'failure OpenPrinter'
try:
win32print.StartDocPrinter(hnum,1,('Test',None,None))
except:
print 'failure startdocprint'
#win32print.WritePrinter(hnum,'This is a test\n')
try:
dc=win32ui.CreateDCFromHandle(hnum)
except:
print 'failure getting DC'
return
# output to DC
hdc=dc.GetHandleAttrib()
dib.draw(hdc, (0, 0) + img.size)
#dib.expose(hdc)
win32print.WritePrinter(hnum, dib)
# close DC
del dc
win32print.EndDocPrinter(hnum)
win32print.ClosePrinter(hnum)
del dib
del img
print "Successfully printed"
if __name__ == "__main__":
im = Image.open("c:\\temp\\test.jpg")
printIm(im)