0

Im trying to run a two for loops that iterate over something like colored large square (for example 300x300) and replacing it with the colors(or pixels) of a smaller square (say 100x100) which is what k and l represent.

Essentially, I was wondering how to keep k and l running between 0-100 and restarting once it hits 100, but also keep i and j running the whole time. I tried used 4 nested for loops but it did not work properly, although I'm starting to think that may be a solution, but that would be very inefficient.

Please let me know if this sounds a little confusing I will try my best to explain more clearly, thanks.

excuse the psuedocode

for (i=0; i < width; i++)
        for (j=0; i< height; j++)
           set(i, j , pixel(k,l));
2
  • What problem are you actually trying to solve here; are you tiling an image onto a larger image, or resizing by nearest-neighbour sampling? Commented Nov 25, 2019 at 3:52
  • @kaya3 tiling an image over a larger image, so basically each smaller image in this example would be 100x100 so it would be 3 images across and 3 down for a 300x300. Commented Nov 25, 2019 at 4:41

2 Answers 2

1

The problem seems to be to tile an image onto another image. You have width and height for the target image's dimensions, so let's say sourceWidth and sourceHeight are the source image's dimensions (100 by 100, in your example).

To tile an image, you want k == i % sourceWidth and l == j % sourceHeight, so that the pixel you read from the source image "wraps around" the boundaries. These should be invariant conditions. The simplest way to satisfy them is to declare them that way directly:

for(int i = 0; i < width; ++i) {
    int k = i % sourceWidth;
    for(int j = 0; j < height; ++j) {
        int l = j % sourceHeight;
        set(i, j, pixel(k, l));
    }
}

This does a lot of % operations, which could be quite inefficient, but it gives us a correct piece of code to transform. If we are incrementing k and l, then there are two properties needed to maintain the invariants:

  1. k and i are incremented in unison; and l and j are incremented in unison.
  2. When k reaches sourceWidth it must wrap back to 0, likewise for l and sourceHeight.
for(int i = 0, k = 0; i < width; ++i, ++k) {
    if(k == sourceWidth) { k = 0; }
    for(int j = 0, l = 0; j < height; ++j, ++l) {
        if(l == sourceHeight) { l = 0; }
        set(i, j, pixel(k, l));
    }
}

Note that the for loop initialiser and stepper now declare and update two variables, for both loops. This is allowed in Java.

This is likely to be faster than doing a lot of % operations, but note that branching with if statements can also slow down an algorithm, so you may want to benchmark it to be sure.

In the special case where source image's dimensions are powers of two, we can achieve the same result with a fast bitwise operation: i % sourceWidth will be equivalent to i & (sourceWidth - 1):

// special case: sourceWidth and sourceHeight are powers of 2
int wMask = sourceWidth - 1, hMask = sourceHeight - 1;
for(int i = 0, k = 0; i < width; ++i, ++k) {
    for(int j = 0, l = 0; j < height; ++j, ++l) {
        set(i, j, pixel(i & wMask, j & hMask));
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I tried to implement something like the second code you wrote but it didn't work properly, but I was able to figure it out after reading your response, very appreciated.
0

It could be done by something like this:

for (i = 0; i < width; i++) {
    for (j = 0; j < height; j++) {
      if(k > 100) {
        k = 0;
      }

      if(l > 100) {
        l = 0;
      }

      k++;
      l++;

      set(i, j , pixel(k,l));
    }
}

1 Comment

I failed to mention that 'l' has to cycle through to 100 while k= 0 and same for k=1, similar to a nested for-loop, again which is what I tried but couldn't get to work properly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.