- 创建一个可以随机排列的可迭代对象,例如列表。
- 将每个元素定义为像素坐标,如(0, 0)、(0, 1)、(0, 2)等。
- 使用特定种子初始化随机数生成器
.
- 随机播放列表。
将会出现一个随机顺序的像素坐标列表。通过按顺序迭代其成员,您将按随机顺序遍历像素,而无需两次访问相同的像素。由于您每次都使用相同的种子初始化 PRNG,因此保证随机顺序相同。
示例
假设您有一个 2x3 图像。它的像素列表如下所示。
[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]
用特定种子洗牌后,它可能看起来像这样。
[[1, 2], [0, 2], [1, 1], [0, 1], [1, 0], [0, 0]]
因此,如果您想修改 3 个像素,它们将是 [1, 2]、[0, 2] 和 [1, 1]。
代码
从概念上讲,您可以使用如上所述的列表列表来执行此操作。然而,从性能角度来说,最好将整数列表从 0 到 n-1 打乱,其中 n 是像素数。您可以通过一除一模运算将这些数字转换为像素坐标。如果您想包含彩色平面,您可以轻松地将其扩展到 3 维。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
class ShufflePixels {
private static List<Integer> shuffleIntegers(int n, long seed) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
list.add(i);
}
Collections.shuffle(list, new Random(seed));
return list;
}
public static void main(String[] args) {
int height = 2;
int width = 3;
long seed = 34758L;
List<Integer> pixelOrder = shuffleIntegers(height * width, seed);
for (int pixel : pixelOrder) {
int x = pixel / width;
int y = pixel % width;
System.out.println(x + " " + y);
}
}
}