pixel graphics

edited July 2014 in Android Mode

Does anyone know how to/ is it possible to draw pixel style graphics with processing, or more specifically how/ can I resize a pimage without blending/smoothing it out? Thanks. Nate

Answers

  • Is your question specific to Android? Because it seems quite generic...

    And the answer is: yes. Actually, Processing mostly works at the pixel level, except perhaps in OpenGL mode which manipulates shapes. But we still have access to the pixels if needed.

  • I would like to know if its possible to resize a pimage without blending / smoothing. Specifically on android.

  • Processing will do no smoothing if you do not do so manually.

    You are probably used to using the image() method with only 3 parameters. Well, when you're drawing your image (using image(), of course), just add a second pair of parameters, specifying the width and height of the image you want to be on screen.

    Your final method call should look something like this:

    image(myPImage, imageX, imageY, imageWidth, imageHeight);
    

    You will fill in your variables and values respectively to those parameters. I must warn you to be careful with resizing. If you want to keep all pixels on screen nice and even, you need to apply the same scale to both imageWidth and imageHeight.

    I'm no expert with PImage, but I think if that "rule" isn't followed, then Processing will automatically scale and/or skip pixels depending on the circumstances.

    Either that, or Processing uses nearest-neighbour interpolation.

  • edited July 2014

    Also, regardless of whether or not it's Android, you're still using Processing. I'm sure you'll be fine.

  • Here is an example of what @MenteCode said:

    PGraphics p;
    
    void setup() {
      size(300,300);
      noSmooth(); // <<<  this is important, remove to see
      p= createGraphics(10, 10);
      p.beginDraw();
      p.background(150);
      p.noStroke();
      p.fill(30);
      for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
          if ((i+j)%2==0) {
            p.rect(i, j, 1, 1);
          }
        }
      }
      p.get();
      p.endDraw();
    }
    
    void draw() {
      background(200);
      image(p,20,20);
      image(p,50,50,200,200);
    }
    
  • I hope you are not a student and this you Master's thesis or something...

  • For p.rect() w/ more definition, use p.smooth(4)! O:-)

  • edited July 2014

    @GoToLoop This was a little bit of code that you helped me with, I think on the old forum, for making a grid that I wanted to generate. I've changed it a bit and I still don't understand:

    if ((i+j)%2==0)

    or if it is even necessary for this purpose. Thanks again!

  • edited July 2014

    It's necessary to determine odd or even! Adding up both row & column values together
    have the additional effect of each row starting off either empty or filled!

    A slightly performance alternative: if ((i+j & 1) == 0). *-:)

    And a faster alternative for p.rect(i, j, 1, 1); too: p.set(i, j, #202020);.

  • Found out an even faster bitwise calculus: \m/
    if (((i^j) & 1) == 0)

  • edited July 2014

    i don't think he really means smoothing in the way we do

    // scaling problem
    import processing.opengl.*;
    
    PImage img;
    void setup() {
      size(320, 320);
      img = loadImage("test.png");
      image(img, 0, 0, 320, 320);  
    }
    

    test.png is any 32x32 image.

    in 1.5.1 with no renderer specified in the size then you get nearest neighbour scaling (which is what he wants). with anything else (P2D, P3D, OPENGL) you get linear or bi-linear or something, some blurry mess.

    i'm guessing that in processing2, which uses opengl by default, you always get this non-nearest neighbour scaling and he wants to turn that off.

    GL_NEAREST is the OpenGL option for this but i don't know how to apply it.

    xyzzy and gotoloop are barking up the wrong tree.

  • xyzzy and gotoloop are barking up the wrong tree.

    I'm not barking on anything, since I'm just commenting on some curious aspects of some answers! :O)

  • edited July 2014

    @koogs is right. I believe this is the good 'ol texture sampling question, which I feel like I have answered so many times on different forums for different versions of Processing. This is not officially supported, but it can be achieved through a 'hack'.

    The current answer (read: for Processing 2.2.1.) is to use the following line:

    ((PGraphicsOpenGL)g).textureSampling(3);

    Code Example

    PImage img = loadImage("someTinyImage.png");
    
    void setup() {
      size(500, 500, P2D);
      ((PGraphicsOpenGL)g).textureSampling(3);
    }
    
    void draw() {
      background(255);
      image(img, 0, 0, width, height);
    }
    
  • Found out an even faster bitwise calculus: 
    if (((i^j) & 1) == 0)
    

    You enjoy confusing people don't you :)

  • edited July 2014

    You enjoy confusing people don't you?

    I enjoy spreading knowledge and choices:

    • if ((i+j) % 2 == 0)
    • if ((i+j & 1) == 0)
    • if (((i^j) & 1) == 0)
  • Amnon and koogs are correct that's what I'm trying to do. But neither answer works on android. :(

  • Oh, didn't realise this was android-specific. I never work with android, so I am not aware of differences with regular Processing. So I also don't know if such differences, like here, are considered a bug. What I gather from android's repo is that it in fact has the same textureSampling() method as the regular repo. In that sense it might be considered a bug. On the other hand, textureSampling as mentioned is not officially supported, so it can never be filed as a bug. I'll leave it up to you if you wish to continue that path or not.

    With regard to a workaround. You can use pixel operations to create the image you want, using the resize/pixel style you want. Main disadvantage of this method is of course higher memory costs. But it may be a workaround until you find a better solution.

    Here is a method that you could use for that:

    PImage img = loadImage("someTinyImage.png");
    
    void setup() {
      size(500, 500, P2D);
      img = resizeBasic(img, 50);
    }
    
    void draw() {
      background(255);
      image(img, 0, 0);
    }
    
    PImage resizeBasic(PImage in, int factor) {
      PImage out = createImage(in.width * factor, in.height * factor, RGB);
      in.loadPixels();
      out.loadPixels();
      for (int y=0; y<in.height; y++) {
        for (int x=0; x<in.width; x++) {
          int index = x + y * in.width;
          for (int h=0; h<factor; h++) {
            for (int w=0; w<factor; w++) {
              int outdex = x * factor + w + (y * factor + h) * out.width;
              out.pixels[outdex] = in.pixels[index];
            }
          }
        }
      }
      out.updatePixels();
      return out;
    }
    
Sign In or Register to comment.