0

I'm writing a program for a college course. I import a .PPM file saved as a 2-d array from main into the function. Then I have to update the pixels of a graphics window (which is opened in main) using .setPixel and color_RGB() method and functions.

The pixels are updating, however there is a white pixel in between each colored pixel for some reason. It's not the PPM file (they were supplied by my professor and I've tried multiple ones), so it has to be my function.

Warning: I am not allowed to use anything in my program that we have not yet covered in our course (it's a first year, 4 month course so the scope is not massive). I don't need to know exactly HOW to fix it, as much as I need to know why it's doing it (AKA: I need to be able to explain how I fixed it, and why it was breaking in the first place).

Here is my function:

def Draw_Pic(pic,pic_array, sizeX, sizeY, gfx_window):

for y in range(sizeY):

    for x in range(0, sizeX, 3):

        pixel_color = color_rgb(pic_array[y][x],pic_array[y][x+1],pic_array[y][x+2])


        pic.setPixel(x,y,pixel_color)
        gfx_window.update()
Bart
  • 19,692
  • 7
  • 68
  • 77
Pyrok
  • 53
  • 1
  • 7
  • 1
    Hint: you cannot use the same x variable to index into the RGB array and into the image, doing so, you end up setting only 1 in 3 pixel in the image. – mjv Apr 25 '12 at 04:30
  • Ok, so what would be the best route to fix this? As I mentioned in the other comment, perhaps introducing a counter variable outside of the loop that will add 1 to the x location for every iteration? Although, that seems like it might fail when the array starts back over for each new row. – Pyrok Apr 25 '12 at 04:47

1 Answers1

0

You are using range(0, sizeX, 3) which creates a list with values 0 to sizeX with increment 3.

So your x goes 0..3..6..9 etc. Makes perfect sense for the part where you assemble pixel color from 3 components, but then you do pic.setPixel(x,y,colors) using the same interleaved x.

Hope that helped.

P.S. By the way, why "colors" and not "color"?

edit Also, that way you'll copy only 1/3 of the image in pic_array.

zrslv
  • 1,748
  • 1
  • 14
  • 25
  • I just used colors as a variable name, I switched a few of the variable names around when I copied my function into the message box due to my university having some strange policies about "plagiarism". One of my roommates friends got suspended for a year for plagiarizing himself, so I thought it best not to take any chances. Also, any suggestions on how to solve my problem, perhaps setting up a different counter variable outside the loop and have it just add 1 to x during every iteration? – Pyrok Apr 25 '12 at 04:45
  • My point is `colors` is confusing. You could rename it into `pixel_color` or something. – zrslv Apr 25 '12 at 04:48
  • Iterate 0..width, then use x*3, x*3+1, x*3+2 to access each component. – zrslv Apr 25 '12 at 04:48
  • Also, you probably should not update window after each `setPixel` call, that is not necessary and can cause a performance impact. – zrslv Apr 25 '12 at 04:51
  • colors has been renamed, and I'm so sorry but I still don't fully understand (in my defense I've been working on this program nearly non-stop for the last 10 hours). Are you saying to set a variable equal to zero to iterate the RGB_color values with, and leave the x for .setPixel()? – Pyrok Apr 25 '12 at 04:52
  • I just set up the update like I was instructed, would it be better to call it outside of the nested loop but still inside of the original? – Pyrok Apr 25 '12 at 04:53
  • I'm not sure what is your import format. I believe each pixel is represented by three elements in pic_array (red component for that pixel, green and blue), like this: R G B R G B R G B. – zrslv Apr 25 '12 at 04:54
  • That is correct, for the file I'm currently testing, each "row" of the array is made up of 15 elements which are representing 5 pixels total, with 3 digits for each pixel just like you thought. For instance, the first row looks similar to this, 0 0 0 0 0 0 0 0 0 15 0 15 0 1 8, (with quotations and brackets of course). – Pyrok Apr 25 '12 at 04:57
  • So my suggestion is to iterate x like this: `for x in range(0, sizeX):` (so it will go through each value) and inside the loop assemble each pixel color from it's components: `color_rgb(pic_array[y][x*3],pic_array[y][x*3+1],pic_array[y][x*3+2])`. – zrslv Apr 25 '12 at 04:58
  • I hope [x*3], [x*3+1], [x*3+2] make sense to you, you really have to understand where does this come from. – zrslv Apr 25 '12 at 04:59
  • I _think_ that I do, since the range is now (0, max X value), the x value is going to be every number at some point instead of stepping in 3's like I had it previously. As such, using *3 and then adding 0, 1, or 2 depending on the position allows it to grab every index of the array. First iteration: 0*3 = 0, 0*3+1 = 1, 0*3+2 = 2, Second iteration: 1*3 = 3, 1*3+1 = 4, 1*3+2 = 5, etc etc etc... I do indeed understand that part – Pyrok Apr 25 '12 at 05:06
  • Honestly, I'm unsure. In all of the in-class examples, update was called inside the nested loops I believe, however I may have just written in down in the wrong place indention wise as following syntax indention's are somewhat difficult when writing on notebook paper. – Pyrok Apr 25 '12 at 05:07
  • I'm not sure what library do you use, but the usual meaning of "window.update" is "present all the changes I've made so far to the user". Why would you want to do that after each pixel (or even pixel row)? – zrslv Apr 25 '12 at 05:12
  • Zelle graphics library, I _believe_. And I honestly just did it because I think that's how it was shown in the examples in class. And I have a strange request, would you mind to delete your 3rd comment from the bottom, the one where you offered your suggestion on how to iterate for X. I only ask this due to the plagiarism policies at my university, I've worked so hard for my grade in this class and I fully understand how and why you suggested what you did, so I'm not missing out on the learning. My school just uses some type of software to check for plagiarism and I'm not sure if... – Pyrok Apr 25 '12 at 05:16
  • your comment containing my code snippet would set it off. I was trying to think of a way to re-word it, but without changing the "x" in the loop which wouldn't' make much sense considering that it also modifies the x coordinate, I can't think of anyway to do that. – Pyrok Apr 25 '12 at 05:17
  • Sorry, that's not how this site is supposed to work. Also, I'd not worry about that piece of code, it's pretty common. Rename "x" to "column_no" and "y" to "row_no" in your code if you'll sleep better that way. – zrslv Apr 25 '12 at 05:22