import Image, ImageFilter, ImageDraw, os, string, ImageFont, calendar # GLOBAL VARIABLE DECLARATION strRootPath = "C:/Data/ActiveData/Development/Website/NewSite-20101103-Expts" strTopTitleImagesRaw = strRootPath + "/new/TheCommonImages/TopTitleImagesRaw" strBannerLocation = "CommonImages/TopTitleImages" strTopTitleImagesProcessed = strRootPath + "/new/Site" + "/" + strBannerLocation strTemplatesPath = strRootPath + "\\ReportTemplates" strTemplateName = "SiteTemplate" strAlbumFolderPathName = "01-DigitalPhotographs" strAlbumFolder = "06-MultiMedia" + "/" + strAlbumFolderPathName strAlbumPath = strRootPath + "/new/Site" + "/" + strAlbumFolder strBannerPage = strRootPath + "/new/Site/06-MultiMedia/05-Banners" strThumbnailFolder = "Thumbnails" intThumbWidth = 750 strGenFile = "MetaAutoContent.txt" # Auto generates this file to show up on the Multi Media | Banners Page strLongGenFile = "MetaAutoContent-Long.txt" # Reads this one on the Digital Photo Albums page to look for which album(s) the banner photos came from! strReadError = "---ERROR---" # Value when a file reading has resulted in an error intLogLevel = 3 # 0 for Start/Stop, 1 for Listing Each Image/Page Name, 2 for Results of Each Image/Page, 3 for Calcs inside Each Image/Page strOutFile = "jpgOutFile" # Base Output Image File Name - The Actual Image Name should be contextual and will be added to the name intTopLength = 2000 # Width / Length of the Top Title Image intTopHeight = 300 # Height of the Top Title Image strLogoPath = strRootPath + "/new/Site/Logos/SandhirLogo.jpg" # Top Left Logo intLogoWidth = 284 intLogoHeight = 96 intLogoXOffset = 25 intLogoYOffset = 25 intShadowBlur = 100 intShadowOffset = 10 strSiteName = strRootPath + "/new/Site/Logos/SandhirName.jpg" # Bottom Right Site Name intNameWidth = 200 intNameXReverseOffset = 15 intNameYReverseOffset = 15 intShadowWidth = 20 intShadowStart = 50 intShadowEnd = 255 intSwishStarts = -250 intSwishEnds = intTopLength intSwishHeight = 75 strLeftNavBgdPath = "new/Site/Backgrounds/172.jpg" strLeftNavBgdProcPath = "new/Site/Backgrounds/172proc.jpg" intLeftNavWidth = 300 binTopOverlaysLeftNav = 0 # 0 makes the top image hover over the left nav, otherwise it is flush with it intNavHeightPerEntry = 10 strHomePageName = "Home" strIndexPageName = "index.html" strHomePagePath = strRootPath + "/" + strHomePageName strContentTextFileName = "ContentText.txt" strContentHtmlFileName = "ContentHtml.txt" lstSpecialFolders = ["MetaImages", "MetaAttachments"] lstSiteMap = [] strLeftNavHtml = "" def fnLog(strLog, intWhichLogLevel): # if intLogLevel > (intLogLevel - 1): print if intLogLevel > (intWhichLogLevel - 1): print strLog # if intLogLevel > (intLogLevel - 1): print "-----------------------------------------------" def fnShadow(i): if i > 250: return 0 if i > 200: return 250 - (i - 200) * 5 if i < 200: return 255 return 255 def fnShadow2(i): if i > 254: return 0 return 255 def fnApplyLogo(imgTheImage, strLogoPath): try: # LOAD THE LOGO fnLog("LOGO: %s" % strLogoPath, 2) imgLogo = Image.open(strLogoPath) # RESIZE LOGO AS REQUIRED fnLog("Resizing logo from %s to %s" % (intLogoWidth, int(float(intLogoWidth) * float(imgLogo.size[1]) / float(imgLogo.size[0]))), 3) imgLogo = imgLogo.resize((intLogoWidth, int(float(intLogoWidth) * float(imgLogo.size[1]) / float(imgLogo.size[0]))), Image.ANTIALIAS) # APPLY SHADOW FIRST # imgLogoShadow = imgLogo.filter(ImageFilter.BLUR) # imgTheImage.paste(imgLogoShadow, (intLogoXOffset + intShadowOffset, intLogoYOffset + intShadowOffset, intLogoXOffset + intLogoWidth + intShadowOffset, intLogoYOffset + intShadowOffset + int(float(intLogoWidth) * float(imgLogo.size[1]) / float(imgLogo.size[0]))), imgLogo.split()[1].point(lambda i: intShadowBlur)) # APPLY LOGO ON IMAGE imgTheImage.paste(imgLogo, (intLogoXOffset, intLogoYOffset, intLogoXOffset + intLogoWidth, intLogoYOffset + int(float(intLogoWidth) * float(imgLogo.size[1]) / float(imgLogo.size[0]))), imgLogo.split()[1].point(lambda i: fnShadow(i))) fnLog("DONE APPLYING LOGO", 2) except: pass return imgTheImage def fnApplySwish(imgTheImage): drwDrawing = ImageDraw.Draw(imgTheImage) # drwDrawing.line((50,50,100,100), fill=(50,50,50)) for intLineNumber in range(1, int(intSwishHeight * 1.1)): intGray = intShadowStart + (intShadowEnd - intShadowStart) * float(intLineNumber / float(intShadowWidth)) if intGray > 255: intGray = 255 # fnLog("Line number %d" % intLineNumber, 4) for intX in range(intSwishStarts, intSwishEnds): # 12(x-.8)^3+5(x-.8)^2+3 # (12(x-.8)^3+6(x-.8)^2+2.25)/2.5 # For x from 0 to 1, y swishes from 0 to 2.5 # Swish fine tuned at http://webgraphing.com/graphing_basic.jsp fltX = float(intX - intSwishStarts) / float(intSwishEnds - intSwishStarts) fltY = 12 * (pow(fltX - 0.8, 3)) + 6 * (pow(fltX - 0.8, 2)) + 2.25 intY = intTopHeight - int(fltY / 2.5 * intSwishHeight) + intLineNumber # if intLogLevel > 2: # print "x/y@z: %d/%d/%d" % (intX, intY, intGray) if intLineNumber == 1: # fnLog("Raw:[%s,%s], Pixels:[%s,%s], Gray:%s" % (fltX, fltY, intX, intY, intGray), 4) pass if (intX < intLeftNavWidth - intShadowOffset) & (binTopOverlaysLeftNav): intGray2 = 255 else: intGray2 = intGray if (intY <= intTopHeight): drwDrawing.point((int(intX), int(intY)), fill=(int(intGray2), int(intGray2), int(intGray2))) return imgTheImage def fnApplyName(imgTheImage, strNamePath): # LOAD THE NAME fnLog("NAME: %s" % strNamePath, 2) print os.listdir(".") imgName = Image.open(strNamePath) # RESIZE Name AS REQUIRED fnLog("Resizing Name from %s to %s" % (intNameWidth, int(float(intNameWidth) * float(imgName.size[1]) / float(imgName.size[0]))), 3) imgName = imgName.resize((int(intNameWidth), int(float(intNameWidth) * float(imgName.size[1]) / float(imgName.size[0]))), Image.ANTIALIAS) # APPLY SHADOW FIRST # imgNameShadow = imgName.filter(ImageFilter.BLUR) # imgTheImage.paste(imgNameShadow, (intNameXOffset + intShadowOffset, intNameYOffset + intShadowOffset, intNameXOffset + intNameWidth + intShadowOffset, intNameYOffset + intShadowOffset + int(float(intNameWidth) * float(imgName.size[1]) / float(imgName.size[0]))), imgName.split()[1].point(lambda i: intShadowBlur)) # APPLY Name ON IMAGE imgTheImage.paste(imgName, (intTopLength - intNameWidth - intNameXReverseOffset, intTopHeight - int(float(intNameWidth) * float(imgName.size[1]) / float(imgName.size[0])) - intNameYReverseOffset, intTopLength - intNameXReverseOffset, intTopHeight - intNameYReverseOffset), imgName.split()[1].point(lambda i: fnShadow(i))) drwDraw = ImageDraw.Draw(imgTheImage) # use a bitmap font # fntFont = ImageFont.truetype("..\\..\\Fonts\\GIL_____.TTF", 25) # drwDraw.text((10, 25), "Hello, World", font=fntFont, fill=(255, 0, 0)) fnLog("DONE APPLYING Name", 2) return imgTheImage def fnApplyLeftNavTop(imgTheImage, strLeftNavBgdPath): # LOAD THE BGD fnLog("NAME: %s" % strLeftNavBgdPath, 2) imgBgd = Image.open(strLeftNavBgdPath) # RESIZE BGD AS REQUIRED fnLog("Resizing Background from %s to %s" % (imgBgd.size[0], intLeftNavWidth), 3) imgBgd = imgBgd.resize((intLeftNavWidth, intTopHeight), Image.ANTIALIAS) # APPLY SHADOW ON THE RIGHT OF THE BGD for intShadowLine in range(1, intShadowOffset): intGray = intShadowStart * 2 + (intShadowEnd - (intShadowStart * 2)) * float(intShadowLine / float(intShadowOffset)) drwDrawing = ImageDraw.Draw(imgBgd) drwDrawing.line((intLeftNavWidth - intShadowOffset + intShadowLine, 0, intLeftNavWidth - intShadowOffset + intShadowLine, intTopHeight), fill=(intGray, intGray, intGray)) # SAVE UPDATED BGD IMAGE imgBgd.save(strLeftNavBgdProcPath, "JPEG") fnLog("Saved updated Nav Background: %s" % strLeftNavBgdProcPath, 3) # CROP CURRENT AREA OF TOP TITLE FOR LATER USE imgBackup = imgTheImage.crop((0, 0, intLeftNavWidth, intTopHeight)) imgBackup.save("..\\Temp.BMP", "BMP") # PASTE THE BGD fnLog("%s/%s:%s/%s" % (intLeftNavWidth, intTopHeight, imgBgd.size[0], imgBgd.size[1]), 3) imgTheImage.paste(imgBgd, (0, 0, intLeftNavWidth, intTopHeight), imgBgd.split()[1].point(lambda i: 255)) # APPLY BACK THE ORIGINAL TOP LEFT # imgTheImage.paste(imgBackup, (0, 0, intLeftNavWidth, intTopHeight), imgBackup.split()[1].point(lambda i: fnShadow2(i))) imgBackup = Image.open("..\\Temp.BMP") imgTheImage.paste(imgBackup, (0, 0, intLeftNavWidth, intTopHeight), imgBackup.split()[0].point(lambda i: fnShadow(i))) # APPLY SHADOW FIRST # imgNameShadow = imgName.filter(ImageFilter.BLUR) # imgTheImage.paste(imgNameShadow, (intNameXOffset + intShadowOffset, intNameYOffset + intShadowOffset, intNameXOffset + intNameWidth + intShadowOffset, intNameYOffset + intShadowOffset + int(float(intNameWidth) * float(imgName.size[1]) / float(imgName.size[0]))), imgName.split()[1].point(lambda i: intShadowBlur)) fnLog("DONE APPLYING BGD", 2) return imgTheImage def fnMerge2Images(strImage1Name, strImage2Name): # LOAD THE IMAGES if intLogLevel > 1: print "RAW:" imgImage1 = Image.open(strImage1Name) if intLogLevel > 1: print imgImage1.format, imgImage1.size, imgImage1.mode imgImage2 = Image.open(strImage2Name) if intLogLevel > 1: print imgImage2.format, imgImage2.size, imgImage2.mode # RESIZE THE IMAGES INTO THE TOP TITLE BAR DIMENSIONS ... PLS MAKE SURE THE IMAGES ARE NOT TOO FAR OFF TO BEGIN WITH imgImage1 = imgImage1.resize((intTopLength, intTopHeight), Image.ANTIALIAS) imgImage2 = imgImage2.resize((intTopLength, intTopHeight), Image.ANTIALIAS) if intLogLevel > 1: print "REGULARIZED:" if intLogLevel > 1: print imgImage1.format, imgImage1.size, imgImage1.mode if intLogLevel > 1: print imgImage2.format, imgImage2.size, imgImage2.mode # DEFINE A BOX WITH THE SIZE OF THE TOP TITLE BAR tupBox1 = (0, 0, intTopLength, intTopHeight) # INITIALIZE THE BAND COUNTER, INCREMENTS OF EACH BAND intNumberOfBands = 100 intBandTop = 0 # MERGE THE TWO IMAGES BAND BY BAND, CHANGING THE TRANSPARENCY AS WE GO ALONG for intBand in range(1, intNumberOfBands + 1): # DETERMINE SIZE AND LOCATION OF BAND intBandBottom = intBandTop + tupBox1[3] / intNumberOfBands - 0 intTransparency = intBand * 255 / intNumberOfBands if intLogLevel > 1: print "Merging band from %s to %s with a transparency of %s" % (intBandTop, intBandBottom, intTransparency) # MERGE ONE WITH THE OTHER USING A TRANSPARENCY MASK imgSection = imgImage2.crop((0, intBandTop, tupBox1[2], intBandBottom)) imgImage1.paste(imgSection, (0, intBandTop, tupBox1[2], intBandBottom), imgSection.split()[1].point(lambda i: intTransparency)) intBandTop = intBandBottom + 0 return imgImage1 def fnPrepareTheImage(strImage1Name): # LOAD THE IMAGES fnLog("RAW:", 2) imgImage1 = Image.open(strImage1Name) # PARSE PROCESSING GUIDANCE lstProcessing1 = string.split(strImage1Name, "-") fnLog(lstProcessing1, 3) lstProcessing2 = string.split(lstProcessing1[1], ".") lstProcessing2[0] = string.replace(lstProcessing2[0], "p", ".") fnLog(lstProcessing2, 3) lstProcessing3 = string.split(lstProcessing2[0], "x") fnLog(lstProcessing3, 3) # SCALE THE IMAGE intOldWidth = imgImage1.size[0] intNewWidth = int(imgImage1.size[0] / float(lstProcessing3[0])) intNewHeight = int(imgImage1.size[1] / float(lstProcessing3[0])) imgImage1 = imgImage1.resize((intNewWidth, intNewHeight), Image.ANTIALIAS) # CROP THE IMAGE intXCrop = int(float(lstProcessing3[1]) / float(lstProcessing3[0])) intYCrop = int(float(lstProcessing3[2]) / float(lstProcessing3[0])) imgImage1 = imgImage1.crop((intXCrop, intYCrop, intXCrop + intTopLength, intYCrop + intTopHeight)) fnLog("Old width = %s" % intOldWidth, 2) fnLog("New width = %s" % intNewWidth, 2) fnLog("Shifted by (x,y), scaled = (%s, %s)" % (intXCrop, intYCrop), 2) return imgImage1, lstProcessing1[0] def fnTopTitleProcessing(): print "TOP TITLE IMAGE PROCESSING:" print "===========================" # GO TO THE FOLDER WITH THE SOURCE IMAGES os.chdir(strTopTitleImagesRaw) lstImages = os.listdir(".") fnLog("Images found: %s" % lstImages, 1) # MERGE AND SAVE THE IMAGES # fnMerge2Images("img_0587[1].jpg", "img_0926[1].jpg").save(strOutFile + ".jpg", "JPEG") intCounter = 0 strArrTopImages = "" for strAnImagePath in lstImages: print ">>>>>>>>>>>>> " + strAnImagePath if strAnImagePath == "Thumbs.db": continue intCounter = intCounter + 1 if intLogLevel > 1: print if intLogLevel > 0: print "Preparing the image %d: %s" % (intCounter, strAnImagePath) if intLogLevel > 1: print "-----------------------------------------------" # SIZE AND CROP THE IMAGE fnLog("Preparing the image", 2) imgAnImage, strImageName = fnPrepareTheImage(strAnImagePath) # APPLY TOP LEFT LOGO WITH SHADOW imgAnImage = fnApplyLogo(imgAnImage, strLogoPath) # APPLY BOTTOM SWISH WITH SHADOW imgAnImage = fnApplySwish(imgAnImage) # APPLY BOTTOM LEFT NAME/LOGO WITHOUT SHADOW imgAnImage = fnApplyName(imgAnImage, strSiteName) # APPLY ICONS TO THE LEFT OF THE BOTTOM LEFT NAME # APPLY THE LEFT NAV MENU BACKGROUND # imgAnImage = fnApplyLeftNavTop(imgAnImage, strLeftNavBgdPath) # SAVE THE IMAGE fnLog("Saving the image", 2) imgAnImage.save("%s/%s%03d-%s.jpg" % (strTopTitleImagesProcessed, strOutFile, intCounter, strImageName), "JPEG") if intCounter > 1: strArrTopImages = strArrTopImages + "," strArrTopImages = strArrTopImages + "\"" + strOutFile + str(intCounter) + "-" + strImageName + ".jpg\"" strDefaultImageName = strOutFile + str(intCounter) + "-" + strImageName + ".jpg" # CREATE HTML SECTION strLogoCoords = "%s, %s, %s, %s" % (intLogoXOffset, intLogoYOffset, intLogoXOffset + intLogoWidth, intLogoYOffset + intLogoHeight) strHtmlSection = """ Home """ % (intTopLength, intTopHeight, intLeftNavWidth, strArrTopImages, strLogoCoords, strDefaultImageName, strDefaultImageName) # lstFiles = os.listdir(".") # fnLog("Files found: %s" % lstImages, 1) print print "DONE" print "===========================" return strHtmlSection def fnParsePosition(strPosition): lstPositionHierarchy = string.split(strPosition, '-') return lstPositionHierarchy def fnBuildPosition(lstPositionHierarchy): intCtr = 0 strPosition = "" for strPositionEntry in lstPositionHierarchy: intCtr = intCtr + 1 if intCtr > 1: strPosition = strPosition + "-" strPosition = strPosition + strPositionEntry return strPosition def fnReadTemplateLines(intTemplateNumber): strRead = strTemplatesPath + "\\" + strTemplateName + "%02d" % intTemplateNumber + ".txt" try: flReader = open(strRead, "r") lstReader = flReader.readlines() flReader.close() except: print "Oops! Could not read %s" % strRead lstReader = [strReadError] strContent = "" for strLine in lstReader: strContent = strContent + strLine return strContent def fnCleanReadLines(strRead): try: flReader = open(strRead, "r") lstReader = flReader.readlines() flReader.close() lstCleanReader = [] for strRead in lstReader: lstCleanReader.append(string.rstrip(strRead, "\n")) except: # print "Oops! Could not read %s" % strRead lstReader = [strReadError] return lstCleanReader def fnFileWrite(strFile, strWrite, chrMode): try: flWriter = open(strFile, chrMode) flWriter.write(strWrite) flWriter.close() except: print "Oops! Could not write %s" % strWrite pass return def fnParseSiteMapEntry(strSiteMapEntry): try: lstEntry = string.split(strSiteMapEntry, "|") if lstEntry[0] == strHomePageName: lstEntry[0] = "00-" + lstEntry[0] lstParent = string.split(lstEntry[0], "-") lstPage = string.split(lstEntry[1], "-") except: return "","","","" return lstParent[0], lstParent[1], lstPage[0], lstPage[1], lstEntry[2] # SPLITS YYYYMMDD-ThisIsTheNameOfTheAlbum to MM DD, YYYY - This Is The Name Of The Album FOR ALBUM OR STORY NAMES def fnSplitFileName(strFolderName): strSplit5 = "" intCtr2 = 0 for chrChar in strFolderName: if ((chrChar.isupper())): if ((intCtr2 > 0) and ((strFolderName[intCtr2 - 1].isupper()))): strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + " " + chrChar elif ((chrChar.isdigit())): if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isdigit()))): strSplit5 = strSplit5 + chrChar else: strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + chrChar intCtr2 = intCtr2 + 1 return strSplit5.strip() # SPLITS YYYYMMDD-ThisIsTheNameOfTheAlbum to MM DD, YYYY - This Is The Name Of The Album FOR ALBUM OR STORY NAMES def fnSplitFileName2(strFolderName): strSplitName = "" strSplit1 = "Year" strSplit2 = "0" strSplit3 = "Year" strSplit4 = "" strSplit5 = "" lstSplit1 = string.split(strFolderName,'-') if len(lstSplit1) == 1: lstSplit1.append(lstSplit1[0]) lstSplit1[0] = time.strftime("%Y%m%d") if len(lstSplit1[0]) > 3: strSplit1 = lstSplit1[0][0:4] if len(lstSplit1[0]) > 5: strSplit2 = lstSplit1[0][4:6] if len(lstSplit1[0]) > 7: strSplit3 = lstSplit1[0][6:8] intCtr1 = 0 for strSpliter1 in lstSplit1: if intCtr1 > 0: strSplit4 = strSplit4 + strSpliter1 intCtr1 = intCtr1 + 1 intCtr2 = 0 for chrChar in strSplit4: if ((chrChar.isupper())): if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isupper()))): strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + " " + chrChar elif ((chrChar.isdigit())): if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isdigit()))): strSplit5 = strSplit5 + chrChar else: strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + chrChar intCtr2 = intCtr2 + 1 strSplitName = calendar.month_name[int(strSplit2)] + " " + strSplit3+ ", " + strSplit1 + " - " + strSplit5 strSplitDate = calendar.month_name[int(strSplit2)] + " " + strSplit3+ ", " + strSplit1 strSplitWhat = strSplit5 return [strSplitName, strSplitDate, strSplitWhat] def fnBuildBannerPage(): # BUILD LIST OF BANNERS AND PARSE NAMES INTO INFO strBannerPath = strTopTitleImagesProcessed lstBannerList = sorted(os.listdir(strBannerPath)) lstBannerPageList = [] # BUILD THUMBNAILS FOR THE BANNERS strThumbnailPath = strBannerPage + "/" + strThumbnailFolder for strBannerImageFile in lstBannerList: if string.split(strBannerImageFile, ".")[1].lower() == "jpg": try: # LOAD THE IMAGE imgImage1 = Image.open(strBannerPath + "/" + strBannerImageFile) # SCALE THE IMAGE intOldWidth = imgImage1.size[0] intNewWidth = intThumbWidth intNewHeight = int( float(imgImage1.size[1]) * (float( float(intThumbWidth) / float(intOldWidth) ) )) imgImage1 = imgImage1.resize((intNewWidth, intNewHeight), Image.ANTIALIAS) # SAVE THE THUMBNAIL imgImage1.save(strThumbnailPath + "/" + "Thumb-" + strBannerImageFile, "JPEG") # IF ALL THIS WORKS, REGISTER THIS BANNER lstBannerPageList.append(strBannerImageFile) except: pass print "%d banners found and successfully processed." % len(lstBannerPageList) # LOAD DIGITAL ALBUM AUTO GENERATED CONTENT AND PARSE TO FIND ALL ALBUMS strDigitalAlbumPage = strAlbumPath + "/" + strLongGenFile lstDigitalAlbumLines = fnCleanReadLines(strDigitalAlbumPage) lstDigitalAlbumList = [] for strDigitalAlbumLine in lstDigitalAlbumLines: if strDigitalAlbumLine[:9].lower() == "\n" strBannerHtml = strBannerHtml + "\n" % (strBannerThumbPath, strBannerCaption) strBannerHtml = strBannerHtml + "" strBannerHtml = strBannerHtml + "
%s
%s\n" strBannerHtml = strBannerHtml + "%s - %s
\n" % (strBannerDateString, strBannerImageLink, strBannerCaption) if len(lstPossibleAlbums) > 0: intCtr = -1 for lstDigitalAlbum in lstPossibleAlbums: intCtr = intCtr + 1 if intCtr == 0: strBannerHtml = strBannerHtml + "Album(s): " strBannerHtml = strBannerHtml + "%s" % (lstDigitalAlbum, lstPossibleAlbumName[intCtr]) if intCtr < len(lstPossibleAlbums) - 1: strBannerHtml = strBannerHtml + ", " strBannerHtml = strBannerHtml + "

" # WRITE AUTO GENERATED CONTENT strAutoGenFile = strBannerPage + "/" + strGenFile fnFileWrite(strAutoGenFile, strBannerHtml, "w") return os.chdir(strRootPath) strPageTop = fnReadTemplateLines(1) strPageTop = strPageTop + fnTopTitleProcessing() fnBuildBannerPage() print print "Done" print strInput = raw_input("Hit enter key to end program")