# I've recently started using iWeb (which for the non # Mac OS X inclined is the application used to make web # sites and what not). # # After creating a 80 page site I was horrified at the # total size site. Nearly 100 MB!! The site really wasn't # very graphics intensive. Each page had only one image on it # at most! I started examining the file structure and was # horrified to realize that iWeb produces web sites use # huge image files. Not even remotely compressed. # # I needed to rescale the jpg and png files down to # reasonable sizes. from PIL import Image import glob import os # this is the default size for images: size = 256, 256 # I provide 2 different sizes for other files # that need to be larger. # Identify the names of the files that need to # be higher quality. csize0files = 'PhotoGray_nav_bg.png', 'bg_round.jpg' csize0 = 768, 768 # different custom sizes for other 'important files # csize1files = 'nonefiles', 'none' csize1 = 512, 512 # create a list for all the files and then add # them all in type by type. # For my page I just had jpg and png images all_matching_files = [] for i in glob.glob("*/*.jpg"): all_matching_files.append(i) for i in glob.glob("*/*.png"): all_matching_files.append(i) # if you are using this for iWeb checkout the file count! # my 80 page site had 3000+ images!!! print "total images to be resized: " + str(len(all_matching_files)) count = len(all_matching_files) # loop through all the images and make changes for infile in all_matching_files: scalesize = size im = Image.open(infile) # split out all the useful parts of the file's path thePath, theFile = os.path.split(infile) fileName, extension = os.path.splitext(theFile) # custom resize if necessary if theFile in csize1files: scalesize = csize1 elif theFile in csize0files: scalesize = csize0 # resize with PIL's awesome thumbnail method im.thumbnail(scalesize, Image.ANTIALIAS) # save back as appropriate type if extension == ".png": im.save(infile, "PNG") else: im.save(infile, "JPEG") count -= 1 if count % 10 == 0: # output some useful stats print str(count) + " images remaining." print "....done" ## output: ## total images to be resized: 3907 ## 3900 images remaining. ## 3890 images remaining. ## ... [snip].....(there were a lot!) ## 30 images remaining. ## 20 images remaining. ## 10 images remaining. ## 0 images remaining. ## ....done # Running this script reduced my website size # from 96MB to 39MB!! # # Certainly there is still room for improvement # future posts will ideally be aimed at further # efficiency gains.
A python example based blog that shows how to accomplish python goals and how to correct python errors.
Showing posts with label PIL. Show all posts
Showing posts with label PIL. Show all posts
Tuesday, October 20, 2009
Python - reduce a web sites size
Monday, September 28, 2009
Python - detect and label objects in images
Image to be analyzed
Detected Objects have now been outlined
from PIL import Image # you'll need to get PIL # some other (shorter) scripts # that use PIL: # create a thumbnail with PIL # find the average image RGB # replace image colors with PIL # # this script is based on the # find the sun script class TheOutliner(object): ''' takes a dict of xy points and draws a rectangle around them ''' def __init__(self): self.outlineColor = 0, 255, 255 self.pic = None self.picn = None self.minX = 0 self.minY = 0 self.maxX = 0 self.maxY = 0 def doEverything(self, imgPath, dictPoints, theoutfile): self.loadImage(imgPath) self.loadBrightPoints(dictPoints) self.drawBox() self.saveImg(theoutfile) def loadImage(self, imgPath): self.pic = Image.open(imgPath) self.picn = self.pic.load() def loadBrightPoints(self, dictPoints): '''iterate through all points and gather max/min x/y ''' # an x from the pool (the max/min # must be from dictPoints) self.minX = dictPoints.keys()[0][0] self.maxX = self.minX self.minY = dictPoints.keys()[0][1] self.maxY = self.minY for point in dictPoints.keys(): if point[0] < self.minX: self.minX = point[0] elif point[0] > self.maxX: self.maxX = point[0] if point[1]< self.minY: self.minY = point[1] elif point[1] > self.maxY: self.maxY = point[1] def drawBox(self): # drop box around bright points for x in xrange(self.minX, self.maxX): # top bar self.picn[x, self.minY] = self.outlineColor # bottom bar self.picn[x, self.maxY] = self.outlineColor for y in xrange(self.minY, self.maxY): # left bar self.picn[self.minX, y] = self.outlineColor # right bar self.picn[self.maxX, y] = self.outlineColor def saveImg(self, theoutfile): self.pic.save(theoutfile, "JPEG") #class CollectBrightPoints(object): # # def __init__(self): # self.brightThreshold = 240, 240, 240 # self.pic = None # self.picn = None # self.brightDict = {} # def loadImage(self, imgPath): # self.pic = Image.open(imgPath) # self.picn = self.pic.load() # def collectBrightPoints(self): # for x in xrange(self.pic.size[0]): # for y in xrange(self.pic.size[1]): # r,g,b = self.picn[x,y] # if r > self.brightThreshold[0] and \ # g > self.brightThreshold[1] and \ # b > self.brightThreshold[2]: # # then it is brighter than our threshold # self.brightDict[x,y] = r,g,b class ObjectDetector(object): ''' returns a list of dicts representing all the objects in the image ''' def __init__(self): self.detail = 4 self.objects = [] self.size = 1000 self.no = 255 self.close = 100 self.pic = None self.picn = None self.brightDict = {} def loadImage(self, imgPath): self.pic = Image.open(imgPath) self.picn = self.pic.load() self.picSize = self.pic.size self.detail = (self.picSize[0] + self.picSize[1])/2000 self.size = (self.picSize[0] + self.picSize[1])/8 # each must be at least 1 -- and the larger # the self.detail is the faster the analyzation will be self.detail += 1 self.size += 1 def getSurroundingPoints(self, xy): ''' returns list of adjoining point ''' x = xy[0] y = xy[1] plist = ( (x-self.detail, y-self.detail), (x, y-self.detail), (x+self.detail, y-self.detail), (x-self.detail, y),(x+self.detail, y), (x-self.detail, y+self.detail),(x, y+self.detail),(x+self.detail,y+self.detail) ) return (plist) def getRGBFor(self, x, y): try: return self.picn[x,y] except IndexError as e: return 255,255,255 def readyToBeEvaluated(self, xy): try: r,g,b = self.picn[xy[0],xy[1]] if r==255 and g==255 and b==255: return False except: return False return True def markEvaluated(self, xy): try: self.picn[xy[0],xy[1]] = self.no, self.no, self.no except: pass def collectAllObjectPoints(self): for x in xrange(self.pic.size[0]): if x % self.detail == 0: for y in xrange(self.pic.size[1]): if y % self.detail == 0: r,g,b = self.picn[x,y] if r == self.no and \ g == self.no and \ b == self.no: # then no more pass else: ol = {} ol[x,y] = "go" pp = [] pp.append((x,y)) stillLooking = True while stillLooking: if len(pp) > 0: xe, ye = pp.pop() # look for adjoining points for p in self.getSurroundingPoints((xe,ye)): if self.readyToBeEvaluated((p[0], p[1])): r2,g2,b2 = self.getRGBFor(p[0], p[1]) if abs(r-r2) < self.close and \ abs(g-g2) < self.close and \ abs(b-b2) < self.close: # then its close enough ol[p[0],p[1]] = "go" pp.append((p[0],p[1])) self.markEvaluated((p[0],p[1])) self.markEvaluated((xe,ye)) else: # done expanding that point stillLooking = False if len(ol) > self.size: self.objects.append(ol) if __name__ == "__main__": print "Start Process"; # assumes that the .jpg files are in # working directory theFile = "3.jpg" theOutFile = "3.output.jpg" import os os.listdir('.') for f in os.listdir('.'): if f.find(".jpg") > 0: theFile = f print "working on " + theFile + "..." theOutFile = theFile + ".out.jpg" bbb = ObjectDetector() bbb.loadImage(theFile) print " analyzing.." print " file dimensions: " + str(bbb.picSize) print " this files object weight: " + str(bbb.size) print " this files analyzation detail: " + str(bbb.detail) bbb.collectAllObjectPoints() print " objects detected: " +str(len(bbb.objects)) drawer = TheOutliner() print " loading and drawing rectangles.." drawer.loadImage(theFile) for o in bbb.objects: drawer.loadBrightPoints(o) drawer.drawBox() print "saving image..." drawer.saveImg(theOutFile) print "Process complete" #output #Start Process #working on A Good Book to Have on Your Shelf.jpg... # analyzing.. # file dimensions: (500, 667) # this files object weight: 146 # this files analyzation detail: 1 # objects detected: 6 # loading and drawing rectangles.. #saving image... #Process complete #working on bamboo-forest.jpg... # analyzing.. # file dimensions: (640, 480) # this files object weight: 141 # this files analyzation detail: 1 # objects detected: 68 # loading and drawing rectangles.. #saving image... # # .............. SNIP .... (I had 20 jpeg files in the dir) # #working on Family_Photo.jpg... # analyzing.. # file dimensions: (4200, 3300) # this files object weight: 938 # this files analyzation detail: 4 # objects detected: 20 # loading and drawing rectangles.. #saving image... #Process complete
Saturday, September 26, 2009
Python - sun image detector - outline objects in an image
The input:
Where oh where is the sun?
Where oh where is the sun?
from PIL import Image # find brightest region of image # and visually identify the region class TheOutliner(object): def __init__(self): self.outlineColor = 0, 255, 255 self.pic = None self.picn = None self.minX = 0 self.minY = 0 self.maxX = 0 self.maxY = 0 def doEverything(self, imgPath, dictPoints, theoutfile): self.loadImage(imgPath) self.loadBrightPoints(dictPoints) self.drawBox() self.saveImg(theoutfile) def loadImage(self, imgPath): self.pic = Image.open(imgPath) self.picn = self.pic.load() def loadBrightPoints(self, dictPoints): # iterate through all points and # gather max/min x/y # an x from the pool (the max/min # must be from dictPoints) self.minX = dictPoints.keys()[0][0] self.maxX = self.minX self.minY = dictPoints.keys()[0][1] self.maxY = self.minY for point in dictPoints.keys(): if point[0] < self.minX: self.minX = point[0] elif point[0] > self.maxX: self.maxX = point[0] if point[1] < self.minY: self.minY = point[1] elif point[1] > self.maxY: self.maxY = point[1] def drawBox(self): # drop box around bright points for x in xrange(self.minX, self.maxX): # top bar self.picn[x, self.minY] = self.outlineColor # bottom bar self.picn[x, self.maxY] = self.outlineColor for y in xrange(self.minY, self.maxY): # left bar self.picn[self.minX, y] = self.outlineColor # right bar self.picn[self.maxX, y] = self.outlineColor def saveImg(self, theoutfile): self.pic.save(theoutfile, "JPEG") class CollectBrightPoints(object): def __init__(self): self.brightThreshold = 240, 240, 240 self.pic = None self.picn = None self.brightDict = {} def loadImage(self, imgPath): self.pic = Image.open(imgPath) self.picn = self.pic.load() def collectBrightPoints(self): for x in xrange(self.pic.size[0]): for y in xrange(self.pic.size[1]): r,g,b = self.picn[x,y] if r>self.brightThreshold[0] and \ g > self.brightThreshold[1] and \ b > self.brightThreshold[2]: # then it is brighter than our threshold self.brightDict[x,y] = r,g,b if __name__ == "__main__": print "Start Process"; # assumes that the test.jpg is in the # working directory theFile = "four.jpg" theOutFile = "four.output.jpg" cbp = CollectBrightPoints() cbp.loadImage(theFile) cbp.collectBrightPoints() brightDict = cbp.brightDict drawer = TheOutliner() drawer.doEverything(theFile, brightDict, theOutFile) print "Process complete"
The output: The sun has been detected!
Friday, September 25, 2009
Python - replace or remove colors from an image
from PIL import Image # this script assumes that 'test.jpg' # is in the current working directory http://pythonicprose.blogspot.com/2009/09/python-os-module-and-working-directory.html n = Image.open('test.jpg') m = n.load() # get x,y size s = n.size # iterate through x and y (every pixel) for x in xrange(s[0]): for y in xrange(s[1]): r,g,b = m[x,y] # remove red from the pic m[x,y] = 0,g,b # save the doctored image n.save('sans_red.jpg', "JPEG") # removing all the red from a photo # makes for a creepy greenish blue (duh..with no red) # try it out!
Tuesday, September 22, 2009
Python - find the average rgb color for an image
# iterate through each pixel in an image and
# determine the average rgb color
# you will need to install the PIL module
from PIL import Image
class PixelCounter(object):
''' loop through each pixel and average rgb '''
def __init__(self, imageName):
self.pic = Image.open(imageName)
# load image data
self.imgData = self.pic.load()
def averagePixels(self):
r, g, b = 0, 0, 0
count = 0
for x in xrange(self.pic.size[0]):
for y in xrange(self.pic.size[1]):
tempr,tempg,tempb = self.imgData[x,y]
r += tempr
g += tempg
b += tempb
count += 1
# calculate averages
return (r/count), (g/count), (b/count), count
if __name__ == '__main__':
# assumes you have a test.jpg in the working directory!
pc = PixelCounter('test.jpg')
print "(red, green, blue, total_pixel_count)"
print pc.averagePixels()
# for my picture the ouput rgb values are:
# (red, green, blue, total_pixel_count)
# (135, 122, 107, 10077696)
#
# you can see that my image had 10,077,696 pixels and python/PIL
# still churned right through it!
python - create thumbnail with PIL
#PIL is the python image library
# learn more about pil
from PIL import Image
# the size of thumbnail you would like to create
# NOTE: you may get from the 100,100 that the image is ... or will be square
# PIL takes care of this and keeps the proper aspect ratio
# the values you enter here are the max
thumbSize = 100, 100
# assumes you have a file called 'test.jpg' in
# the current directory
# how to tell where python's current directory
pic = Image.open("test.jpg")
# PIL makes thumbnails easy with the thumbnail method
pic.thumbnail(thumbSize, Image.ANTIALIAS)
# save to file and choose save type
pic.save("test.small.jpg", "JPEG")
Wednesday, July 15, 2009
Python - compare two images
# PIL is a great python library for doing everything related to images # check out the other PIL and Image examples: # Find and Label objects in Images l # Find and outline the sun # Replace or remove colors from an image # Find the average RGB color for and image # Determine an image's type (regardless of extension) # here is the zipped full source for this example from PIL import Image import time import sys def compareTwoPics(picture_1, picture_2, step=20): step = int(step) if step < 1: step = 1 percent_similar = 0.0 percent_red = 0.0 percent_green = 0.0 percent_blue = 0.0 percent_totalcolor = 0.0 total_check_points = 0.0 total_not_match = 0.0 percent_similar = 0.0 pic1_total_red = 0 pic1_total_green = 0 pic1_total_blue = 0 pic1_total_color = 0 pic2_total_red = 0 pic2_total_green = 0 pic2_total_blue = 0 pic2_total_color = 0 #print picture_1 #print picture_2 try: pic1 = Image.open(picture_1) pic2 = Image.open(picture_2) except: # tried to open an unsupported format!! #print str(picture_1) + " is not a supported image format" #print str(picture_2) + " is not a supported image format" return -1.0, 0.0, 0.0, 0.0 pic1_width = pic1.size[0] pic1_height = pic1.size[1] pic2_width = pic2.size[0] pic2_height = pic2.size[1] if pic1_width != pic2_width: print "\n widths must be the same \n" sys.exit() if pic1_height != pic2_height: print "\n widths must be the same \n" sys.exit() for x in range(0, pic1_width): for y in range(0, pic1_height): if x % step == 0: pic1_color = pic1.getpixel((x,y)) pic2_color = pic2.getpixel((x,y)) total_check_points += 3 if pic1_color[0] != pic2_color[0]: total_not_match += 1 if pic1_color[1] != pic2_color[1]: total_not_match += 1 if pic1_color[2] != pic2_color[2]: total_not_match += 1 pic1_total_red += pic1_color[0] pic1_total_green += pic1_color[1] pic1_total_blue += pic1_color[2] pic2_total_red += pic2_color[0] pic2_total_green += pic2_color[1] pic2_total_blue += pic2_color[2] #print " pic1 count: "+ str(pic1_total_red) #print " pic2 count: "+ str(pic2_total_red) pic1_total_color = pic1_total_red + pic1_total_green + pic1_total_blue pic2_total_color = pic2_total_red + pic2_total_green + pic2_total_blue percent_similar = 1 - (total_not_match / total_check_points) percent_red = abs(float(pic2_total_red) / float(pic1_total_red)) percent_green = abs(float(pic2_total_green) / float(pic1_total_green)) percent_blue = abs(float(pic2_total_blue) / float(pic1_total_blue)) percent_totalcolor = abs(float(pic2_total_color) / float(pic1_total_color)) print '----' print "total % comparible red: " + str(percent_red) print "total % comparible green:" + str(percent_green) print "total % comparible blue: " + str(percent_blue) print "total % comparible: " + str(percent_totalcolor) print "total pic1: " + str(pic1_total_color) print "total pic2 " + str(pic2_total_color) return percent_similar, percent_totalcolor, pic1_total_color, pic2_total_color if __name__ == '__main__': try: import psyco psyco.full() except ImportError: print "...installing psyco would provide additional performance" thedetail = 20 if len( sys.argv ) < 3: print "\n\n" print "Usage: " + str(sys.argv[0]) + " <photo1.png> <photo2.png> [detail]" print "" print " - photo1.png and photo2.png are the photos you are comparing" print " - detail is just a number. The higher the number the faster" print " and less detailed the comparison will be. Default detail is 20" print "" print "example:" print " # Highest quality comparison, slowest turn around" print " " + str(sys.argv[0]) + " photo.png photo2.png 1" print " " print " # Low quality comparison, high turn around" print " " + str(sys.argv[0]) + " photo.png photo2.png 100" sys.exit() else: try: thedetail = sys.argv[3] except: thedetail = 20 tt = time.time() print str(compareTwoPics(sys.argv[1], sys.argv[2], step=thedetail)) print "execution seconds: " + str(time.time() - tt)
Subscribe to:
Posts (Atom)



