def PilImageToWxImage(pilImage, copyAlpha=True): """Convert PIL image to wx.Image Based on http://wiki.wxpython.org/WorkingWithImages """ from gui_core.wrap import EmptyImage hasAlpha = pilImage.mode[-1] == "A" if copyAlpha and hasAlpha: # Make sure there is an alpha layer copy. wxImage = EmptyImage(*pilImage.size) pilImageCopyRGBA = pilImage.copy() pilImageCopyRGB = pilImageCopyRGBA.convert("RGB") # RGBA --> RGB wxImage.SetData(pilImageCopyRGB.tobytes()) # Create layer and insert alpha values. if wxPythonPhoenix: wxImage.SetAlpha(pilImageCopyRGBA.tobytes()[3::4]) else: wxImage.SetAlphaData(pilImageCopyRGBA.tobytes()[3::4]) else: # The resulting image will not have alpha. wxImage = EmptyImage(*pilImage.size) pilImageCopy = pilImage.copy() # Discard any alpha from the PIL image. pilImageCopyRGB = pilImageCopy.convert("RGB") wxImage.SetData(pilImageCopyRGB.tobytes()) return wxImage
def PilImageToWxImage(pilImage, copyAlpha=True): """Convert PIL image to wx.Image Based on http://wiki.wxpython.org/WorkingWithImages """ from gui_core.wrap import EmptyImage hasAlpha = pilImage.mode[-1] == 'A' if copyAlpha and hasAlpha: # Make sure there is an alpha layer copy. wxImage = EmptyImage(*pilImage.size) pilImageCopyRGBA = pilImage.copy() pilImageCopyRGB = pilImageCopyRGBA.convert('RGB') # RGBA --> RGB fn = getattr(pilImageCopyRGB, "tobytes", getattr(pilImageCopyRGB, "tostring")) pilImageRgbData = fn() wxImage.SetData(pilImageRgbData) fn = getattr(pilImageCopyRGBA, "tobytes", getattr(pilImageCopyRGBA, "tostring")) # Create layer and insert alpha values. if globalvar.wxPythonPhoenix: wxImage.SetAlpha(fn()[3::4]) else: wxImage.SetAlphaData(fn()[3::4]) else: # The resulting image will not have alpha. wxImage = EmptyImage(*pilImage.size) pilImageCopy = pilImage.copy() # Discard any alpha from the PIL image. pilImageCopyRGB = pilImageCopy.convert('RGB') fn = getattr(pilImageCopyRGB, "tobytes", getattr(pilImageCopyRGB, "tostring")) pilImageRgbData = fn() wxImage.SetData(pilImageRgbData) return wxImage
def _export(self, exportInfo, decorations): size = self.frame.animationPanel.GetSize() if self.temporalMode == TemporalMode.TEMPORAL: timeLabels, mapNamesDict = self.temporalManager.GetLabelsAndMaps() frameCount = len(timeLabels) else: frameCount = self.animationData[ 0].mapCount # should be the same for all animWinSize = [] animWinPos = [] animWinIndex = [] legends = [anim.legendCmd for anim in self.animationData] # determine position and sizes of bitmaps for i, (win, anim) in enumerate(zip(self.mapwindows, self.animations)): if anim.IsActive(): pos = win.GetPosition() animWinPos.append(pos) animWinSize.append(win.GetSize()) animWinIndex.append(i) images = [] busy = wx.BusyInfo(_("Preparing export, please wait..."), parent=self.frame) wx.GetApp().Yield() lastBitmaps = {} fgcolor = UserSettings.Get(group="animation", key="font", subkey="fgcolor") bgcolor = UserSettings.Get(group="animation", key="font", subkey="bgcolor") for frameIndex in range(frameCount): image = EmptyImage(*size) image.Replace(0, 0, 0, 255, 255, 255) # collect bitmaps of all windows and paste them into the one for i in animWinIndex: frameId = self.animations[i].GetFrame(frameIndex) if not UserSettings.Get(group="animation", key="temporal", subkey=["nodata", "enable"]): if frameId is not None: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap else: if i not in lastBitmaps: lastBitmaps[i] = wx.NullBitmap() else: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap im = ImageFromBitmap(lastBitmaps[i]) # add legend if used legend = legends[i] if legend: legendBitmap = self.bitmapProvider.LoadOverlay(legend) x, y = self.mapwindows[i].GetOverlayPos() legImage = ImageFromBitmap(legendBitmap) # not so nice result, can we handle the transparency # otherwise? legImage.ConvertAlphaToMask() im.Paste(legImage, x, y) if im.GetSize() != animWinSize[i]: im.Rescale(*animWinSize[i]) image.Paste(im, *animWinPos[i]) # paste decorations for decoration in decorations: # add image x = decoration["pos"][0] / 100.0 * size[0] y = decoration["pos"][1] / 100.0 * size[1] if decoration["name"] == "image": decImage = wx.Image(decoration["file"]) elif decoration["name"] == "time": timeLabel = timeLabels[frameIndex] if timeLabel[1]: # interval text = _("%(from)s %(dash)s %(to)s") % { "from": timeLabel[0], "dash": "\u2013", "to": timeLabel[1], } else: if (self.temporalManager.GetTemporalType() == TemporalType.ABSOLUTE): text = timeLabel[0] else: text = _("%(start)s %(unit)s") % { "start": timeLabel[0], "unit": timeLabel[2], } decImage = RenderText(text, decoration["font"], bgcolor, fgcolor).ConvertToImage() elif decoration["name"] == "text": text = decoration["text"] decImage = RenderText(text, decoration["font"], bgcolor, fgcolor).ConvertToImage() image.Paste(decImage, x, y) images.append(image) del busy # export pilImages = [WxImageToPil(image) for image in images] self.busy = wx.BusyInfo(_("Exporting animation, please wait..."), parent=self.frame) wx.GetApp().Yield() try: def export_avi_callback(event): error = event.ret del self.busy if error: GError(parent=self.frame, message=error) return if exportInfo["method"] == "sequence": filename = os.path.join( exportInfo["directory"], exportInfo["prefix"] + "." + exportInfo["format"].lower(), ) writeIms(filename=filename, images=pilImages) elif exportInfo["method"] == "gif": writeGif( filename=exportInfo["file"], images=pilImages, duration=self.timeTick / float(1000), repeat=True, ) elif exportInfo["method"] == "swf": writeSwf( filename=exportInfo["file"], images=pilImages, duration=self.timeTick / float(1000), repeat=True, ) elif exportInfo["method"] == "avi": thread = gThread() thread.Run( callable=writeAvi, filename=exportInfo["file"], images=pilImages, duration=self.timeTick / float(1000), encoding=exportInfo["encoding"], inputOptions=exportInfo["options"], bg_task=True, ondone=export_avi_callback, ) except Exception as e: del self.busy GError(parent=self.frame, message=str(e)) return if exportInfo["method"] in ("sequence", "gif", "swf"): del self.busy
def _export(self, exportInfo, decorations): size = self.frame.animationPanel.GetSize() if self.temporalMode == TemporalMode.TEMPORAL: timeLabels, mapNamesDict = self.temporalManager.GetLabelsAndMaps() frameCount = len(timeLabels) else: frameCount = self.animationData[ 0].mapCount # should be the same for all animWinSize = [] animWinPos = [] animWinIndex = [] legends = [anim.legendCmd for anim in self.animationData] # determine position and sizes of bitmaps for i, (win, anim) in enumerate(zip(self.mapwindows, self.animations)): if anim.IsActive(): pos = win.GetPosition() animWinPos.append(pos) animWinSize.append(win.GetSize()) animWinIndex.append(i) images = [] busy = wx.BusyInfo(_("Preparing export, please wait..."), parent=self.frame) wx.Yield() lastBitmaps = {} fgcolor = UserSettings.Get(group='animation', key='font', subkey='fgcolor') bgcolor = UserSettings.Get(group='animation', key='font', subkey='bgcolor') for frameIndex in range(frameCount): image = EmptyImage(*size) image.Replace(0, 0, 0, 255, 255, 255) # collect bitmaps of all windows and paste them into the one for i in animWinIndex: frameId = self.animations[i].GetFrame(frameIndex) if not UserSettings.Get(group='animation', key='temporal', subkey=['nodata', 'enable']): if frameId is not None: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap else: if i not in lastBitmaps: lastBitmaps[i] = wx.NullBitmap() else: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap im = ImageFromBitmap(lastBitmaps[i]) # add legend if used legend = legends[i] if legend: legendBitmap = self.bitmapProvider.LoadOverlay(legend) x, y = self.mapwindows[i].GetOverlayPos() legImage = ImageFromBitmap(legendBitmap) # not so nice result, can we handle the transparency # otherwise? legImage.ConvertAlphaToMask() im.Paste(legImage, x, y) if im.GetSize() != animWinSize[i]: im.Rescale(*animWinSize[i]) image.Paste(im, *animWinPos[i]) # paste decorations for decoration in decorations: # add image x = decoration['pos'][0] / 100. * size[0] y = decoration['pos'][1] / 100. * size[1] if decoration['name'] == 'image': decImage = wx.Image(decoration['file']) elif decoration['name'] == 'time': timeLabel = timeLabels[frameIndex] if timeLabel[1]: # interval text = _("%(from)s %(dash)s %(to)s") % { 'from': timeLabel[0], 'dash': u"\u2013", 'to': timeLabel[1] } else: if self.temporalManager.GetTemporalType( ) == TemporalType.ABSOLUTE: text = timeLabel[0] else: text = _("%(start)s %(unit)s") % \ {'start': timeLabel[0], 'unit': timeLabel[2]} decImage = RenderText(text, decoration['font'], bgcolor, fgcolor).ConvertToImage() elif decoration['name'] == 'text': text = decoration['text'] decImage = RenderText(text, decoration['font'], bgcolor, fgcolor).ConvertToImage() image.Paste(decImage, x, y) images.append(image) del busy # export pilImages = [WxImageToPil(image) for image in images] busy = wx.BusyInfo(_("Exporting animation, please wait..."), parent=self.frame) wx.Yield() try: if exportInfo['method'] == 'sequence': filename = os.path.join( exportInfo['directory'], exportInfo['prefix'] + '.' + exportInfo['format'].lower()) writeIms(filename=filename, images=pilImages) elif exportInfo['method'] == 'gif': writeGif(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), repeat=True) elif exportInfo['method'] == 'swf': writeSwf(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), repeat=True) elif exportInfo['method'] == 'avi': writeAvi(filename=exportInfo['file'], images=pilImages, duration=self.timeTick / float(1000), encoding=exportInfo['encoding'], inputOptions=exportInfo['options']) except Exception as e: del busy GError(parent=self.frame, message=str(e)) return del busy