import os
import pygame, sys
from pygame.locals import K_a, K_s,K_w,K_d,K_LEFTBRACKET,K_RIGHTBRACKET, K_RIGHT, K_LEFT, QUIT
from PIL import Image
pygame.init()
'''
main() sets these (perhaps differently), so make changes down there.
If you cut/copy this code somewhere you need these variables globally,
or make it a class and make these attributes.
'''
resolution = 300 #the resolution (in dpi) the resulting cropped images should have.
infile_folder = '.' #path to folder images to process are in. '.' is the folder this script is in
infile_prefix = "album80-86_" #prefix common to all the images you'd like to access
start_page = 1 #which page to start on. 0 is the first page.
outfile_folder= "./cropped"
outfile_prefix = "photo80-86_"
outfile_extension = "jpg" #must be three character extension with no period. Why? Because I am lazy. So no "jpeg", okay?
BG_COLOR = (0,0,0)
def displayRect(screen, px, topleft, prior,pos,scale):
# ensure that the rect always has positive width, height
if topleft == None:
#func was called without a topleft, which means clear the previous rectangle
screen.fill(BG_COLOR)
rect = px.get_rect()
px = pygame.transform.scale(px,[int(rect.width/scale), int(rect.height/scale)])
screen.blit(px, (rect[0]-pos[0],rect[1]-pos[1]))
pygame.display.flip()
return None
#or, the usual situation, topleft is defined, so blit over the old rect and blit in the new.
topleft = [(val/scale-pos[i]) for i,val in enumerate(topleft)]
x, y = topleft
bottomright = pygame.mouse.get_pos()
width = bottomright[0] - topleft[0]
height = bottomright[1] - topleft[1]
if width < 0:
x += width
width = abs(width)
if height < 0:
y += height
height = abs(height)
# eliminate redundant drawing cycles (when mouse isn't moving)
current = x, y, width, height
if not (width and height):
return current
if current == prior:
return current
# draw transparent box and blit it onto canvas
rect = px.get_rect()
px = pygame.transform.scale(px,[int(rect.width/scale), int(rect.height/scale)])
screen.blit(px, (rect[0]-pos[0],rect[1]-pos[1]))
im = pygame.Surface((width, height))
im.fill((128, 128, 128))
pygame.draw.rect(im, (32, 32, 32), im.get_rect(), 1)
im.set_alpha(128)
screen.blit(im, (x, y))
pygame.display.flip()
# return current box extents
return (x, y, width, height)
def setup(px):
screen = pygame.display.set_mode( px.get_rect()[2:] )
screen.blit(px, px.get_rect())
pygame.display.flip()
return screen, px
def move(pos,scale,px,screen):
x,y = pos
#print pos,x
rect = px.get_rect()
screen.fill(BG_COLOR)
px = pygame.transform.scale(px,[int(rect.width/scale), int(rect.height/scale)])
screen.blit(px, (rect[0]-x,rect[1]-y))
pygame.display.flip()
#px.rect.topleft = pr.rect.topleft[0] - x,
def mainLoop():
topleft = bottomright = prior = None
n=0
scale = 1
pos = [0,0]
#create list of files matching prefix in folder, and sort it
# input_loc = first file #input_loc = 'album86-92_003.jpg'
infiles = []
len_prefix = len(infile_prefix)
for fname in os.listdir(infile_folder):
if fname[:len_prefix] == infile_prefix:
if fname[-3:] in ['jpg','png']:
infiles.append(fname)
infiles.sort()
file_idx = start_page
try:
infile = infiles[file_idx]
except IndexError:
print "the start page you requested is beyond the scope of the files loaded.\nYou have been taken to the last page instead."
file_idx = len(infiles)-1
infile = infiles[file_idx]
#get files begining with output prefix, grab suffixes and sort.
#but, if folder does not exist or is empty, just start at 0
outfiles = []
len_prefix = len(outfile_prefix)
try:
for fname in os.listdir(outfile_folder):
if fname[:len_prefix] == outfile_prefix:
outfiles.append(fname)
except OSError:
os.makedirs(outfile_folder)
out_idx = 0
else:
outfiles.sort()
try:
out_idx = int(outfiles[-1][len_prefix:-4])+1
except ValueError:
print "Egad! Not all files with the output prefix specified end with a number followed by a three character extension\nMaybe start a new output folder?"
print "...Quitting"
return 0
except IndexError:
#folder exisits but is empty
out_idx = 0
input_loc = os.path.join(infile_folder,infile)
screen, px = setup(px = pygame.image.load(input_loc))
outfilename = outfile_prefix+str(out_idx).zfill(3)+'.'+outfile_extension
output_loc = os.path.join(outfile_folder,outfilename)
while n!=1:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit(0)
if event.type == pygame.MOUSEBUTTONUP:
if not topleft:
topleft = [(val+pos[i])*scale for i,val in enumerate(event.pos)]
#print "tr: ",topleft
else:
bottomright = [(val+pos[i])*scale for i,val in enumerate(event.pos)]
#print "br: ",bottomright
if event.type == pygame.KEYDOWN and event.key == K_a:
pos = [pos[0]-200,pos[1]]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_d:
pos = [pos[0]+200,pos[1]]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_w:
pos = [pos[0],pos[1]-200]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_s:
pos = [pos[0],pos[1]+200]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_RIGHTBRACKET:
scale = scale/1.25
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_LEFTBRACKET:
scale = scale*1.25
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_RIGHT:
file_idx += 1
try:
infile = infiles[file_idx]
#print "file_idx: ",file_idx
except IndexError:
file_idx -= 1
print "End of album"
#raise
else:
input_loc = os.path.join(infile_folder,infile)
px = pygame.image.load(input_loc)
pos = [0,0]
topleft = bottomright = prior = None
prior = displayRect(screen, px, topleft, prior,pos,scale)
if event.type == pygame.KEYDOWN and event.key == K_LEFT:
if file_idx == 0:
print "This is the begining of the album, cannot go back a page."
else:
#print "file_idx",file_idx
file_idx -= 1
infile = infiles[file_idx]
input_loc = os.path.join(infile_folder,infile)
px = pygame.image.load(input_loc)
pos = [0,0]
topleft = bottomright = prior = None
prior = displayRect(screen, px, topleft, prior,pos,scale)
if topleft:
#first corner has been selected
prior = displayRect(screen, px, topleft, prior,pos,scale)
if bottomright:
#selection has been made!
left, upper, right, lower = ( topleft + bottomright )
# ensure output rect always has positive width, height
if right < left:
left, right = right, left
if lower < upper:
lower, upper = upper, lower
im = Image.open(input_loc)
im = im.crop(( int(left), int(upper), int(right), int(lower)))
dpi = resolution
im.save(output_loc, dpi = (dpi,dpi))
out_idx += 1
outfilename = outfile_prefix+str(out_idx).zfill(3)+'.'+outfile_extension
output_loc = os.path.join(outfile_folder,outfilename)
topleft = bottomright = prior = None
prior = displayRect(screen, px, topleft, prior,pos,scale)
print "saved"
return
if __name__ == "__main__":
os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
print'''
Hello!
This program exists to speed up cropping out many sections from larger images
while also changing the resolution of the cropped images.
The Zudell family photo album was scanned at 600 dpi resolution.
The default resolution for cropped images is 300 dpi.
'''
resolution = raw_input('enter new integer resolution, or nothing for default: ')
os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
try: resolution = int(resolution)
except:
print '\nNo new resolution specified, using 300 dpi'
resolution = int(300)
dirs = []
for f in os.listdir('.'):
if os.path.isdir(f):
dirs.append(f)
print '''\n\n\n\n
now, enter the name of the directory you want to work on. here is a list of sub
directories within this current directory:\n'''
if dirs:
for dir in dirs: print dir
else:
print "oops, there are no sub-directories here"
print "\n\nenter nothing or nonsense to use the current directory"
path = raw_input("enter directory to use: ")
infile_folder = path.strip()
os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
if os.path.isdir(infile_folder):
pass
elif os.path.isdir('./'+infile_folder):
infile_folder = './'+infile_folder
else:
print "no valid directory entered, using current"
infile_folder = '.'
for f in os.listdir(infile_folder):
print f
if not os.listdir(infile_folder):
print "oh... There aren't any files at all in here"
d = raw_input("press enter to quit")
pygame.display.quit()
print '''\n\n
You may choose a filename prefix so that only some of the images in this dir
are available for editing. all files in this directory are listed above. \n'''
infile_prefix = raw_input('input file prefix (or nothing to use all files): ')
os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
print '''\n\n
You may choose a prefix for output files also. they will go in the ./cropped folder.\n'''
outfile_prefix = raw_input('output file prefix (or nothing for default): ')
if not outfile_prefix: outfile_prefix = "image_"
os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
print '''
Use the left ard right arrows to change image.
'[' and ']' zoom out and in, respectively.
click and drag a box to crop.
too move around:
w
asd
And come back to this screen to see unnecessary messages.
'''
raw_input('\npress enter to begin')
mainLoop()
pygame.display.quit()