user1475777
user1475777

Reputation: 90

Pygame with strange variable issues - a couple variables are increasing for unknown reason

I am having a really strange problem with Pygame, and it's got me stumped for the last few (OK, more like 5) hours. There are free programs out there for making photo mosaics, but ever since my early days tinkering with VB5, I've wanted to write my own version. You know how that is. I have all kinds of cool parts written for loading source images, finding color averages and everything. But here I'm stuck and confused. So very stuck and confused.

This part of the program converts a 'target image' (the one that will be made up of small source images) to smaller blocks of color that other source images will try to match and then replace eventually. But for some reason, the size of the blocks keeps increasing with every iteration. I've tried so many different things that I've had to go through the script and delete out a bunch of things and add a couple more comments before posting.

The target img is a 1280x800 random google image, but any other picture should work just the same. Watch as the Y size of the blit increases with every block going down, and the X size increases as new rows are made. I hard coded in a set size for the solid color rectangle (2 pixels across, much smaller than I'll use), but for whatever reason this keeps increasing. The first row of blits is so small right now that it's hard to see. That quickly changes. **Here's the link to what I am the image I'm using (http://www.travelimg.org/wallpapers/2012/01/iceland-golden-falls-druffix-europe-golden-falls-golden-falls-iceland-natur-waterfall-waterfalls-800x1280.jpg), but any other pic/size renamed to target.jpg should do the same.

If anyone can point me in the right direction it would be much appreciated. I want to cover this whole source pic in nice 12x12 blocks of solid color to start with. I can't figure out what is changing these block sizes as it goes.

import pygame
import os
from time import sleep

okformats = ['png','jpg','bmp','pcx','tif','lbm','pbm','pgm','ppm','xpm']

targetimg = 'C:\\Python27\\mosaic\\target.jpg'

if targetimg[-3:] not in okformats:
    print 'That format is unsupported, get ready for some errors...'
else:
    print 'Loading...'


pygame.init()
screen = pygame.display.set_mode((100,100)) #picked a size just to start it out
clock = pygame.time.Clock() #possibly not needed in this script

targetpic = pygame.image.load(targetimg).convert()

targetrect = targetpic.get_rect()  #returns something like [0,0,1280,800]
targetsize = targetrect[2:]
targetw = targetrect[2]
targeth = targetrect[3]

numpicsx = 100 #number of pictures that make up the width
sourceratio = 1  #testing with square pics for now
picxsize = targetw/numpicsx
numpicsy = targeth/(picxsize*sourceratio)
picysize = targeth/numpicsy


print 'Blitting target image'
screen = pygame.display.set_mode(targetsize)
screen.fill((255,255,255)) #set to white in case of transparency
screen.blit(targetpic,(0,0))

#update screen
pygame.display.update()
pygame.display.flip()
clock.tick(30)

SLOWDOWN = .1  #temp slow down to watch it

print numpicsx #here are some print statements just to show all the starting values are correct
print numpicsy
print '---'
print picxsize
print picysize

sleep(1)

for x in xrange(numpicsx):

    for y in xrange(numpicsy):
    currentrect = [x*picxsize,y*picysize,x*picxsize+picxsize,y*picysize+picysize]

    avgc = pygame.transform.average_color((targetpic), currentrect) #average color
    avgc = avgc[:3]  #drops out the alpha if there is one

    pygame.draw.rect(screen, avgc, currentrect)
    #pygame.draw.rect(screen, avgc, (currentrect[0],currentrect[1],currentrect[0]+2,currentrect[1]+2))  #hard coded 2s (rather than 12s in this case) to help pin point the problem

    pygame.display.update()
    pygame.display.flip()
    clock.tick(30) #probably not needed

    sleep(SLOWDOWN)


print 'Done./nSleeping then quitting...'
sleep(3)

pygame.quit()

Upvotes: 0

Views: 160

Answers (1)

user1475777
user1475777

Reputation: 90

A friend of mine took a look at my code and showed me the problem. I was thinking that the rect format for drawing was (x1,y1,x2,y2), but it's actually (x,y,width,height). This is the new line:

currentrect = [x*picxsize,y*picysize,picxsize,picysize]

I also dropped the clock.tick(30) lines to speed it all up.

Upvotes: 0

Related Questions