Loading...
Logo
Processing Forum

Pixel Sorting - Curves

in General Discussion  •  Other  •  8 months ago  
Hi guys, 

So I'm relatively new to processing, and certainly new to code in general; this is all very interesting and quite hard for me. And great fun.

I've been doing simple pixel sorting processing, similar to that of Kim Asendorf (but much much simpler) and Adam Ferris.
The best example though would be this blog. The code he's using are simple enough for me to get my head around but still have very interesting results.

My question is therefore this: 

How (as I'm sure it is possible) would I use code so that the final image exhibits curves in the lines of pixels? Rather than straight horizontal or even zigzagged lines; curves of varying lengths?

I appreciate the frustration it's easy to get with someone like me who doesn't really know what they're talking about, but I wanna learn, thats what matters eh?

I hope some of you processing geniuses have an idea.

Thanks for reading my long question, 

Sam

Replies(14)

The code reorder pixels following a given algorithm: detect some condition in the color of a pixel, swap it with another pixel, or get the color of another pixel.
Most of the time, the result is probably random and unexpected: it is a matter of experiments.
With such algorithm, it is unlikely to get a given shape, curve or something else. Unless perhaps you try some different kind of algorithm, using a positional condition instead of one based on color.
Curves are not a very easy thing to describe programmatically, maybe you should try making a path that is some section of an arc of a circle first.

For example, pick some point on the screen, I'll call it A. Pick another point on the screen, I'll call it B, and B is defined as some distance from A (a radius distance). To make things easier, say that B is exactly above A so that B.x == A.x and B.y < A.y (because decreasing y values in Processing means up). I'll pick an arbitrary radius just to give it a number, say 10. Another point defined as being a distance (more or less due to pixel rounding) of 10 from A could be C. C would be the next point that is a part of the circle going clockwise (relative to B). You would have to do some math to make sure C has integer values for C.x and C.y, but basically it would be slightly to the right and / or down from B. Do whatever color comparisons you want between B and C. If the comparison returns the result that C should inherit some color from B, then you continue the process with another point D. D would also be a distance of 10 from A but further clockwise relative to B or C. You would do the test again to see if D inherits some color from C and so on.

To make it more interesting, you can randomize the radius distance so that it is not always 10. If you study curve programatic representations then you might be able to generalize this process to make curves that are not arcs, but that would be much more complicated.

Edit: Picking clockwise was also arbitrary, you could also randomly pick counter-clockwise and it would work, but then C would be to the left / down from B. Additionally, if you get this working well, B would not need to be absolutely above A, it could be anywhere on the circle some distance from A.
Maybe this will help...


Note that " pixel sorting", while commonly used, is an abuse of language.
The code I saw actually overwrites some pixels with others, duplicating pixels, loosing others.
That's not what I call "sorting", which would swap pixels but never loose one.
Of course, that's not important, as long as the result is looking good, but I find the term confusing and misleading.
That's all useful, thanks a lot for the help. using parts of a circle is a good idea, but a bit more time than I have currently (I'm producing a book cover)

One last question though, this is the code I'm using at the mo:

Copy code
  1. int mode = 0;

  2. //Pixel Sorting - Cat Ba Color/Noise

  3. int threshold;

  4. int loops = 1;

  5. PImage img;
  6. String imgFileName = "dashboard";
  7. String fileType = "jpeg";

  8. boolean saved = false;

  9. void setup() {
  10.   img = loadImage(imgFileName+"."+fileType);
  11.   size(img.width, img.height);
  12.   frameRate(12);
  13.   image(img, 0, 0);
  14. }

  15. void draw(){
  16.   img.loadPixels();
  17.     for (int k=width; k<width*height-width; k++){
  18.       if (threshold < 200) {
  19.         if (brightness(img.pixels[k]) > threshold){
  20.           img.pixels[k-1] = color(
  21.           int(red(img.pixels[k-width])),
  22.           int(green(img.pixels[k-width])),
  23.           int(blue(img.pixels[k-width])));
  24.         } else {
  25.           img.pixels[k-width] = color(
  26.           int(red(img.pixels[k+1])),
  27.           int(green(img.pixels[k+1])),
  28.           int(blue(img.pixels[k+1])));
  29.         }
  30.         threshold = threshold+1;
  31.       } else {
  32.         threshold = 0;
  33.       }
  34.       image(img,0,0);
  35.   if(!saved && frameCount >= loops) {
  36.     saveFrame(imgFileName+"_"+mode+".png");
  37.     saved = true;
  38.     println("DONE"+frameCount);
  39.     System.exit(0);
  40.   }

  41.     }
  42.   img.updatePixels();
  43.   image(img,0,0);
  44. }
  45.   

It worked well until I added the chunk to save the image. So far it's only 'sorting' for one frame. I need a lot more than that to achieve anything visually noticeable. Any idea what I'd change?

Cheers again, 

Sam
Hit Ctrl+T to format correctly your code.
You will see that the saveFrame code is within the first loop, so this one will never finish.
You should put this save code at the very end of draw().
Thanks - I didn't know the formatting trick, it makes more sense now. Although when i put it right at the very end i have trouble; it either says I'm mixing active and static modes, or that there are too many '{' when they seem to line up fine. Either an unexpected token, or it doesn't have a partner. Any ideas? Sorry for so many questions, thanks so much for your help. 
Sam
" at the very end of draw()", for me, means "inside draw() but after anything else inside it". Not "after draw()".
The active / static modes means you tried to put it after.
" too many '{' " -> I don't know what you did, so hard to tell. Another trick: if you click after an opening or closing brace, you can see the matching one to be highlighted.


Ok I think I get it, still having a bit of trouble though. This is what I have:

Copy code
  1. int mode = 0;

  2. //Pixel Sorting - Cat Ba Color/Noise

  3. int threshold;

  4. int loops = 1;

  5. PImage img;
  6. String imgFileName = "dashboard";
  7. String fileType = "jpeg";

  8. boolean saved = false;

  9. void setup() {
  10.   img = loadImage(imgFileName+"."+fileType);
  11.   size(img.width, img.height);
  12.   frameRate(12);
  13.   image(img, 0, 0);
  14. }

  15. void draw() {
  16.   img.loadPixels();
  17.   for (int k=width; k<width*height-width; k++) {
  18.     if (threshold < 200) {
  19.       if (brightness(img.pixels[k]) > threshold) {
  20.         img.pixels[k-1] = color(
  21.         int(red(img.pixels[k-width])), 
  22.         int(green(img.pixels[k-width])), 
  23.         int(blue(img.pixels[k-width])));
  24.       } 
  25.       else {
  26.         img.pixels[k-width] = color(
  27.         int(red(img.pixels[k+1])), 
  28.         int(green(img.pixels[k+1])), 
  29.         int(blue(img.pixels[k+1])));
  30.       }
  31.       threshold = threshold+1;
  32.     } 
  33.     else {
  34.       threshold = 0;
  35.     }
  36.     image(img, 0, 0);
  37.     if (!saved && frameCount >= loops)
  38.     }
  39.     img.updatePixels();
  40.   image(img, 0, 0);
  41.   {
  42.     saveFrame(imgFileName+"_"+mode+".png");
  43.     saved = true;
  44.     println("DONE"+frameCount);
  45.     System.exit(0);
  46.   }
  47. }

When trying to run, the '}' at 46 is an 'unexpected token'. Deleting it results in the pairings being odd. I know these are really simple problems, but this is a pretty steep learning curve. Thanks a lot for your help.
I see... An exercised eye see immediately the issue, but for a beginner it is less obvious.
That's why showing code is important: we cannot guess what you did wrong.

You had the brace after the if condition in the wrong direction...
I think you don't even need a test. Something like:
Copy code
  1. int mode = 0;

  2. //Pixel Sorting - Cat Ba Color/Noise
  3. int threshold;

  4. PImage img;
  5. String imgFileName = "dashboard";
  6. String fileType = "jpeg";

  7. void setup() {
  8.   img = loadImage(imgFileName+"."+fileType);
  9.   size(img.width, img.height);
  10.   image(img, 0, 0);
  11. }

  12. void draw() {
  13.   img.loadPixels();
  14.   for (int k=width; k<width*height-width; k++) {
  15.     if (threshold < 200) {
  16.       if (brightness(img.pixels[k]) > threshold) {
  17.         img.pixels[k-1] = color(
  18.         int(red(img.pixels[k-width])),
  19.         int(green(img.pixels[k-width])),
  20.         int(blue(img.pixels[k-width])));
  21.       } else {
  22.         img.pixels[k-width] = color(
  23.         int(red(img.pixels[k+1])),
  24.         int(green(img.pixels[k+1])),
  25.         int(blue(img.pixels[k+1])));
  26.       }
  27.       threshold = threshold+1;
  28.     } else {
  29.       threshold = 0;
  30.     }
  31.   }
  32.   img.updatePixels();
  33.   image(img, 0, 0); 
  34.   saveFrame(imgFileName+"_"+mode+".png");
  35.   println("DONE"+frameCount);
  36.   System.exit(0);
  37. }
might work.
Not tested, but at least it compiles.
Ahaa! That's worked very well. Now, just so I understand and learn a bit more...

What parameter defines how long it proceses for? Like, how extreme the effect is when finished? So I could change it to be shorter or longer... if possible.
Or (sorry just thinking of ideas) would it be possible to code a command that saves the image as it looks at any time? So you have the code without the saving feauture (a copy of what mine was before):

Copy code
  1. //Pixel Sorting - Cat Ba Color/Noise
  2. int threshold;
  3. String url;
  4. PImage img;

  5. void setup(){
  6.   img=loadImage("Screen Shot 2013-02-17 at 13.44.29.png");
  7.   size(img.width,img.height);
  8.   frameRate(12);
  9.   threshold = 135;
  10. }

  11. void draw(){
  12.   img.loadPixels();
  13.     for (int k=width; k<width*height-width; k++){
  14.       if (threshold < 255) {
  15.         if (brightness(img.pixels[k]) > threshold){
  16.           img.pixels[k-1] = color(
  17.           int(red(img.pixels[k-width])),
  18.           int(green(img.pixels[k-width])),
  19.           int(blue(img.pixels[k-width])));
  20.         } else {
  21.           img.pixels[k-width] = color(
  22.           int(red(img.pixels[k+1])),
  23.           int(green(img.pixels[k+1])),
  24.           int(blue(img.pixels[k+1])));
  25.         }
  26.         threshold = threshold+1;
  27.       } else {
  28.         threshold = 0;
  29.       }
  30.     }
  31.   img.updatePixels();
  32.   image(img,0,0);
  33. }

Would there be a way to make it save the whole image on click for example? I'd like to be able to save the whole image at any point, even if it is bigger than the srceen (by screen capturing). Is it possible?

Thanks again for all you're help, I'm actually learning!
Put the lines:
Copy code
  1.   save(imgFileName+"_"+mode+".png");
  2.   println("DONE"+frameCount);
  3.   System.exit(0);
in a keyPressed() or mousePressed() function. Look at them in the Reference to understand how they work.

Works well, thanks for all your help!