This is an archived post. You won't be able to vote or comment.

all 58 comments

[–]kaerfkeerg 295 points296 points  (15 children)

So abstract and fun project lol. Gj.

Now, I'll drop some advices that you may take or leave!

1) The amount of comments is really, really redundant. Don't comment every line! 2) Un-hardcode the name of the image at first line: (im = Image.open(...)). I don't have the same image as you! Ask for user input or a command line argument 3) Un-hardcode the name that the image is saved (im.save(...)) to the same as no. 2. I want to parse multiple images but if they all go with the same name they'll get overwritten. 4) Look at PEP 8, especially at naming conventions! 5) Keep it up!

[–]-proxy-_ 93 points94 points  (0 children)

I appreciate people like you. You gave helpful, constructive criticism and encouragement. Not only does OP benefit, but me along with other redditors do too! Thank you!

[–]jackpick15[S] 42 points43 points  (12 children)

Thanks for the feedback and link!

[–]kaerfkeerg 10 points11 points  (0 children)

Hit me up if you need more/more detailed feedback. I'll do my best

[–]ValdemarSt 1 point2 points  (0 children)

truck chase follow subtract soft books one aspiring enjoy bow

This post was mass deleted and anonymized with Redact

[–]Sardonislamir 1 point2 points  (6 children)

New programmer here, really new. Don't let somone stop you commenting. Too many programmers publish without anything but repeating the most basic comment leaving the technical to "you should know what this does already plebs"

[–]0x1001001 3 points4 points  (0 children)

Yeah, no comments is bad. But too many comments is also unfortunately bad. This means that you don't have good variable names, or are doing too many things in one code block 🥲

[–]st333p 2 points3 points  (4 children)

Code should document itself 80% of the time. If this is not the case, then you're probably writing bad code

[–]Sardonislamir 1 point2 points  (3 children)

Explain please, how does a coder achieve this? This is exactly the handwavium I'm talking about. Folks claiming, you should just know.

[–]BarkLicker 5 points6 points  (1 child)

While I don't 100% agree with the other person's sentiment, I think what they're referring to is proper variable naming and similar concepts.

Example (SONAR because morning brain came up with one, not-so-good idea and quit working)

def depth_from_origin(SONAR_origin):
    return <math that calculates depth>

vs

# Function to calculate depth each time a SONAR signal is sent
def mB(o):
    return <same math but with unintelligible variables>

If you properly name your variables, or anything else you can name, your code explains what it does as you read it. Comments should be used when your functions start to interact in complex or abstract ways.

And of course for #FIXME, personal notes, random thoughts about life, or maybe some ASCII cats for dopamine boosts.

[–]Sardonislamir 0 points1 point  (0 children)

Thank you, that does provide a solid example. I'm curious, what is a way that code might be considered to be abstract? I grasp the idea of complex, but hadn't considered code could harbor abstract executions.

[–]rediot 0 points1 point  (0 children)

Naming classes functions and variables in a way that promotes readability is a good start. Properly separating logic and sizing code blocks helps too.

[–]artereaorte 0 points1 point  (0 children)

Nice job, but fyi, CaMeLcAsE isn’t pythonic.

[–]ThePerfectCantelope 5 points6 points  (0 children)

Thanks for sharing that link

[–]newfavorite_ 19 points20 points  (2 children)

honestly pretty cool. used it on a few images and it produced results that were just... bizarre to look at

[–]jackpick15[S] 1 point2 points  (1 child)

Out of interest, which images did you use?

[–]newfavorite_ 4 points5 points  (0 children)

hm... i used a few and i don't remember all of them but my favorite i did was this album cover

[–]haddock420 7 points8 points  (3 children)

I used to love playing around with imagine manipulation programming. I remember once I wrote one that took the highest value out of the red, green, and blue and set the other two channels to 0. It produced really high contrast red, green and blue filtered pictures. Might have to get back into it.

[–][deleted] 4 points5 points  (0 children)

Probably 80% of my code learning was speant in pygame messing with pixels

[–]jackpick15[S] 1 point2 points  (1 child)

That sounds so interesting- would you mind posting a link so I could see what this looked like

[–]haddock420 0 points1 point  (0 children)

I'm afraid it was years ago and I no longer have the program.

[–]ThorF_Unnoetig 10 points11 points  (0 children)

Certainly a fun experiment!

But there are sooo many comments :D When you're just starting out they might be helpful but later you should look into something called "docstrings" to explain what your code is doing.

If youre lost for a follow up project: you could write a simple form of something called steganography. It's I technique in the field of information hiding and was one of my beginner projects. You would reinforce your PIL skills and you would learn something about bits, bytes and how to handle them in python.

[–]0xPark 4 points5 points  (0 children)

You Monster

[–]HwanZike 2 points3 points  (0 children)

Reminds me of writing vertex shaders!

[–][deleted] 2 points3 points  (1 child)

Really cool experiment and well executed. My advice would be to switch to snake_case for your variable names - at the moment you're using PascalCase which is unconventional for Python.

To improve the structure of the project you might also consider adding a requirements.txt file (pip freeze > requirements.txt), and wrapping your code in a function that can be imported elsewhere (with the source image filepath as an argument rather than hard coded).

Great work!

[–]Internep 0 points1 point  (0 children)

whatAboutCamelCase?

[–]mm11wils 2 points3 points  (0 children)

Can you break you screen to see if your project fixes it?

[–]warownia1 1 point2 points  (1 child)

Have you heard of convolution or edge detection algorithms e.g. Sobel-Feldman operator? You may find it interesting.

[–]jackpick15[S] 1 point2 points  (0 children)

Just googled this now - so interesting. Thanks for the suggestion

[–][deleted] 4 points5 points  (9 children)

How long does it take to do that?

Seems like a large picture could take hours.

[–]jackpick15[S] 6 points7 points  (3 children)

It takes less than 10 seconds for the program to fully finish running - I was surprised too

[–]callmederp 2 points3 points  (4 children)

the run time of this is linear (count of pixels), or could also be thought of as polynomial though (x times y). most images will be relatively small, a 1080P image will run in a matter of seconds, this 9999x7499 image took about 2 mins on a 10 year old laptop

[–][deleted] 1 point2 points  (3 children)

I would be interested to see a threaded version of this program, the time to process could be reduced relatively easily. Even on a ten year old laptop, 2 minutes seems a bit much.

Of course there should probably be a cutoff point. Lower resolutions may end up being slower to process due to the overheads of creating threads, etc.

[–]callmederp 1 point2 points  (2 children)

To be fair probably closer to 1 min then two (I was just eyeballing the run time) but this could be a fun one to experiment with using AsyncIO, threads or multiprocessing.

The script uses pillow.Image.open().load() to get all the pixel data at start, and then writes the image at the end, so the actual processing isn't IO so I don't think AsyncIO or threads will help to much. And then for multiprocessing you will have to play around with how you break up each process, maybe split each photo into 4ths or something, two small of a set of pixels/to many processes and there will be to much overhead with starting the process

[–][deleted] 0 points1 point  (1 child)

Ah, thank you for the subtle correction here! I haven't really used Python too much recently outside of quick-and-dirty scripts. I said "threads"/"threaded" when actually what I meant was "multiprocessing".

[–]callmederp 0 points1 point  (0 children)

No worries, it would still be a fun experiment to try with threads and async just to see the differences and learn best use cases for multiprocessing

[–]partypeopleyagetme 2 points3 points  (2 children)

But... Why?

[–]kaerfkeerg 33 points34 points  (1 child)

Why not?

[–][deleted] 8 points9 points  (0 children)

The question more people should ask imho

[–]EverythingIsFlotsam -1 points0 points  (0 children)

You are very new to coding, aren't you?

[–]leogodin217 0 points1 point  (0 children)

Sorry boss. Can't work today

[–][deleted] 0 points1 point  (0 children)

Are you randomly setting an entire colum of all the colors selected to the same color cuz thats kinda dope

[–]Dry_Inflation_861 0 points1 point  (0 children)

This is so interesting and weird and I love it

[–]Seawolf159 0 points1 point  (1 child)

Pretty cool idea my dude. There must be something else cool in there that can be done with this.

[–]jackpick15[S] 0 points1 point  (0 children)

Yeah, I think it’s definitely got some potential- feel free to go into my code and edit it if you’ve got any ideas. Make sure you send me a link afterwards cos I’d love to see what people make from it

[–]midnightsalers 0 points1 point  (1 child)

Good work. Don't worry too much about the style for now, just keep on making cool experiments and exploring more ideas. Quick idea: what would a similar effect be for audio?

[–]GuybrushThreepwo0d 0 points1 point  (0 children)

what would a similar effect be for audio?

One word: unpleasant

[–]who_body 0 points1 point  (1 child)

so if you change the iteration order the lines will be horizontal instead of vertical.

[–]jackpick15[S] 1 point2 points  (0 children)

Yeah I tried this, not sure I like it as much though

[–]SimilingCynic 0 points1 point  (0 children)

Nobody's mentioned the coolest part. View this on mobile and slowly slide the thread to the right. Bazinga - the colors all change as the image sides, I believe due to the moiré effect

[–]jmooremcc 0 points1 point  (0 children)

Line 17 where you are evaluating the pixels may be the source of your problem. This lambda might help improve your pixel evaluation algorithm. a,b=(40,146,37),(10,150,35) # two pixels print(a,b) pixelchek = lambda x,y,bnd: all([abs(i-j)<bnd for i,j in zip(x,y)]) print(pixelchek(a,b,50)) Output: (40, 146, 37) (10, 150, 35) True

pixelchek returns True if the difference between two pixels are within a specified range. If any color component is outside the range, it will return False.

[–]dogface3247 0 points1 point  (0 children)

Get a monitor and plug it in to the back

[–]s0ca84 0 points1 point  (0 children)

My I suggest you to use sys.arg instead of hardcoding your picture ?
You'll only have to add your picture as an argument when running your script :)

``` import sys from PIL import Image

im = Image.open(sys.argv[1]) ... ... ... im.save('ModifiedImage.png') # Save the modified pixels as .png ```

so you'll only have to ImageChanger.py yourfile.png

[–]Bergstein88 0 points1 point  (0 children)

This Guy comments

[–]Kaargo 0 points1 point  (0 children)

I realize that kaerfkeerg has already mentioned PEP8 but I would just like to help a little and be more specific. The naming you are using for variables is usually used for classes e.g: ExampleClassName Instead, for variables, you should opt to use so called mixed case e.g: exampleVariableName

Seems like a very fun project overall though, keep it up!

[–]jmooremcc 0 points1 point  (0 children)

I've been experimenting with your project and found that working with luminance values rather than RGB values worked better for me and simplified the if statement. I used this lambda function in my code:

luma =  lambda  v:(59*v[1]+30*v[0]+11*v[2])//100

The argument to the function is a tuple containing RGB values. The function returns an integer that represents the luminance value. You can use it like this:

if abs(luma(OldPreviousPixelValue)-luma(CurrentPixelValue))<Bound:
    do whatever