6

The idea of this function is to fade the top half only of the picture (make it gradually darker). Here is what I have but it seems to be making all of the top half solid black.

def fadeDownFromBlack(pic1):

w=getWidth(pic1)
h=getHeight(pic1)

for y in range(0,h/2):
     for x in range(0,w):
        px=getPixel(pic1,x,y) 
        setBlue(px,y*(2.0/h)) 
        setRed(px,y*(2.0/h)) 
        setGreen(px,y*(2.0/h))
TylerH
  • 20,799
  • 66
  • 75
  • 101
roger34
  • 275
  • 2
  • 6
  • 16
  • I assume you're using PIL? (Just checking.) – Tyler Feb 10 '10 at 23:16
  • I don't believe so, no. Unless it comes with Jython 4.3. – roger34 Feb 11 '10 at 00:08
  • From the paper : To darken a pixel you multiply the red, green and blue levels by an appropriate fraction. Specifically, if y is in the top half of the picture, all the pixels in row y have their RGB levels multiplied by y*(2.0/h), where h is the height of the picture. The pixels in the bottom half of the picture are not changed. I'm assuming I don't need to use setBlue etc then? Would I use return? – roger34 Feb 11 '10 at 00:13
  • Okay, I take it my fifth guess at the libraries being used (and therefore the tags to apply to the question) is correct? http://coweb.cc.gatech.edu/mediaComp-plan/94 – badp Feb 11 '10 at 00:30

4 Answers4

4

To darken a pixel you multiply the red, green and blue levels by an appropriate fraction.

What you are doing:

setBlue(px,y*(2.0/h))

What you are being told to do:

setBlue(px,y*(2.0/h) * getBlue(px))
badp
  • 11,409
  • 3
  • 61
  • 89
3

Let's look at just one line here:

setBlue(px,y*(2.0/h))

and key part here is

y*(2.0/h)

y changes, as you go down. Let's try some simple values for y and h. Let's say h is 100 and we will examine when y is both 0 and 50 (h/2). For y = 0, we get 0. For y = 50, we get 1. If your range of values for the colors is 256 with 0 being the darkest, then no wonder this is black. What you have is a range of values from 0. to 1., but I'm guessing what you want is to take that number and times it by the old color value.

What you want is:

setBlue(px,y*(2.0/h)*getBlue(px))

and similar things for the other colors.

Justin Peel
  • 46,722
  • 6
  • 58
  • 80
  • Mind marking this as the accepted answer, then? Click on the checkmark at the side of the question. – badp Feb 11 '10 at 00:56
  • Haha ok thanks I was wondering if there was a way for me to do that or if it was determined by upvotes. – roger34 Feb 11 '10 at 01:06
2

Just to share an enhanced version and add some visuals (because visuals are good)...

# 'divisor' : How much we expand the gradient (less is more)
# 'switch' : If True, start gradient from bottom to top
def fadeDownFromBlack(pic, divisor, switch=False):  

   w = getWidth(pic)
   h = getHeight(pic)


   startY = 0
   endY = min(h-1, int(h/float(divisor)))
   inc = 1

   if (switch):
     startY = h-1
     endY = max(0, h-1 - int(h/float(divisor)))
     inc = -1

   color_ratio = float(divisor)/h

   for y in range(startY, endY, inc): 
       for x in range(0,w):
           px = getPixel(pic, x, y )
           setRed(px, abs(startY - y)*(color_ratio)*getRed(px))
           setGreen(px, abs(startY - y)*(color_ratio)*getGreen(px))
           setBlue(px, abs(startY - y)*(color_ratio)*getBlue(px))


file = pickAFile()
picture = makePicture(file)
# The following commented line answers the question
#fadeDownFromBlack(picture, 2)
fadeDownFromBlack(picture, 0.7, True)

writePictureTo(picture, "/home/mad-king.png")

show(picture)


Output (Painting by Corneliu Baba - The Mad King):


............enter image description here......................enter image description here............


Gauthier Boaglio
  • 10,054
  • 5
  • 48
  • 85
2

Find out what the scale is for the setBlue/Red/Green methods. I assume 0 corresponds to black, but what's the brightest? You seem to be assuming it's 1, but it might actually be 255 or something. Even if it is 1, it looks like this code isn't taking the pixel's old value into account, it's just setting it to an exact color, based on its vertical position. Maybe that's what you want, but I doubt it. You probably want to multiply the pixel's current value by something instead.

Tyler
  • 21,762
  • 11
  • 61
  • 90
  • From the paper : To darken a pixel you multiply the red, green and blue levels by an appropriate fraction. Specifically, if y is in the top half of the picture, all the pixels in row y have their RGB levels multiplied by y*(2.0/h), where h is the height of the picture. The pixels in the bottom half of the picture are not changed. I'm assuming I don't need to use setBlue etc then? Would I use return? – roger34 Feb 11 '10 at 00:14