如何更优雅地遍历(位)图?
How can traversing through a (bit-)map be implemented more elegantly?
总的来说:如何更有效地实现和使用遍历偏移量?
假设我们在下面定义了一个位图。我们如何从一个固定像素开始遍历(在本例中收集)所有附近的像素 - 并最终避免这 8 个 if 语句?
// The bitmap 1920x1080px
RGBColor[][] imageMatrix = new RGBColor[1920][1080];
// Collect all nearby pixels that are not white
ArrayList<RGBColor> neighboringPixels = new ArrayList<RGBColor>();
// Width-index of center pixel
int w = 50;
// Height-index of center pixel
int h = 50;
// Initializing offsets for a more elegant check-up...
int[][] offsets = { { -1, -1 }, { 0, -1 }, { 1, -1 },
{ 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 },
{ -1, 0 } };
// But this is what I came up with
// Get top-left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h - 1]);
}
// Get top pixel
if (!(w < 0 || w > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w][h - 1]);
}
// Get top-right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h - 1]);
}
// Get right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h < 0 || h > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h]);
}
// Get bottom-right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h + 1]);
}
// Get bottom pixel
if (!(w < 0 || w > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w][h + 1]);
}
// Get bottom-left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h + 1]);
}
// Get left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h < 0 || h > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h]);
}
您正在对 3x3 正方形进行迭代:
for (int i=w-1; i<w+2; ++i) {
if (i<0 || i>=255) continue;
for (int j=h-1; j<h+3; ++j) {
if (j<0 || j>=255) continue;
if (i==w && j==h) continue;
neighboringPixels.add(imageMatrix[i][j]);
}
把代码写得尽量简单,让编译器优化。
简单:
for (int i = -1 ; i <= 1 ; i++) {
int wi = w + i;
if (wi >= 0 && wi <= 255) {
for (int j = -1 ; j <= 1 ; j++) {
int hj = h + j;
if (!(i == 0 && j == 0) && hj >= 0 && hj <= 255) {
neighboringPixels.add(imageMatrix[wj][hj]);
}
}
}
}
您当前的代码在最坏情况下包含 32 个条件。
就我得出的代码行而言,或多或少的最小解决方案是这样的:
final int minH = Math.max(0, h - 1);
final int maxH = Math.min(255, h + 1);
final int minW = Math.max(0, w - 1);
final int maxW = Math.min(255, w + 1);
for (int i = minH; i <= maxH; i++)
for (int j = minW; j <= maxW; j++)
if ((i != h) || (j != w))
neighboringPixels.add(imageMatrix[i][j]);
最坏情况下会有4+4*4*2 = 36种情况
在执行时间方面的最小解决方案可能如下所示:
final int prevH = h - 1;
final int minW = Math.max(0, w - 1);
final int nextH = h + 1;
final int maxW = Math.min(255, w + 1);
if ((prevH >= 0) && (prevH <= 255))
for (int i = minW; i <= maxW; i++)
neighboringPixels.add(imageMatrix[prevH][i]);
if ((h >= 0) && (h <= 255)) {
if ( (minW != w) && (minW <= 255) )
neighboringPixels.add(imageMatrix[h][minW]);
if ( (maxW != w) && (maxW >= 0) )
neighboringPixels.add(imageMatrix[h][maxW]);
}
if ((nextH >= 0) && (nextH <= 255))
for (int i = minW; i <= maxW; i++)
neighboringPixels.add(imageMatrix[nextH][i]);
最坏情况2+2+4+6+2+4 = 20个条件
进一步优化:
条件 if ( (a>=0) && (a<=255) )
可以优化为 if ( (a&~0xff) != 0)
但它仅适用于 [0-255]
范围
总的来说:如何更有效地实现和使用遍历偏移量?
假设我们在下面定义了一个位图。我们如何从一个固定像素开始遍历(在本例中收集)所有附近的像素 - 并最终避免这 8 个 if 语句?
// The bitmap 1920x1080px
RGBColor[][] imageMatrix = new RGBColor[1920][1080];
// Collect all nearby pixels that are not white
ArrayList<RGBColor> neighboringPixels = new ArrayList<RGBColor>();
// Width-index of center pixel
int w = 50;
// Height-index of center pixel
int h = 50;
// Initializing offsets for a more elegant check-up...
int[][] offsets = { { -1, -1 }, { 0, -1 }, { 1, -1 },
{ 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 },
{ -1, 0 } };
// But this is what I came up with
// Get top-left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h - 1]);
}
// Get top pixel
if (!(w < 0 || w > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w][h - 1]);
}
// Get top-right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h - 1 < 0 || h - 1 > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h - 1]);
}
// Get right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h < 0 || h > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h]);
}
// Get bottom-right pixel
if (!(w + 1 < 0 || w + 1 > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w + 1][h + 1]);
}
// Get bottom pixel
if (!(w < 0 || w > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w][h + 1]);
}
// Get bottom-left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h + 1 < 0 || h + 1 > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h + 1]);
}
// Get left pixel
if (!(w - 1 < 0 || w - 1 > 255 || h < 0 || h > 255)) {
neighboringPixels.add(imageMatrix[w - 1][h]);
}
您正在对 3x3 正方形进行迭代:
for (int i=w-1; i<w+2; ++i) {
if (i<0 || i>=255) continue;
for (int j=h-1; j<h+3; ++j) {
if (j<0 || j>=255) continue;
if (i==w && j==h) continue;
neighboringPixels.add(imageMatrix[i][j]);
}
把代码写得尽量简单,让编译器优化。
简单:
for (int i = -1 ; i <= 1 ; i++) {
int wi = w + i;
if (wi >= 0 && wi <= 255) {
for (int j = -1 ; j <= 1 ; j++) {
int hj = h + j;
if (!(i == 0 && j == 0) && hj >= 0 && hj <= 255) {
neighboringPixels.add(imageMatrix[wj][hj]);
}
}
}
}
您当前的代码在最坏情况下包含 32 个条件。
就我得出的代码行而言,或多或少的最小解决方案是这样的:
final int minH = Math.max(0, h - 1);
final int maxH = Math.min(255, h + 1);
final int minW = Math.max(0, w - 1);
final int maxW = Math.min(255, w + 1);
for (int i = minH; i <= maxH; i++)
for (int j = minW; j <= maxW; j++)
if ((i != h) || (j != w))
neighboringPixels.add(imageMatrix[i][j]);
最坏情况下会有4+4*4*2 = 36种情况
在执行时间方面的最小解决方案可能如下所示:
final int prevH = h - 1;
final int minW = Math.max(0, w - 1);
final int nextH = h + 1;
final int maxW = Math.min(255, w + 1);
if ((prevH >= 0) && (prevH <= 255))
for (int i = minW; i <= maxW; i++)
neighboringPixels.add(imageMatrix[prevH][i]);
if ((h >= 0) && (h <= 255)) {
if ( (minW != w) && (minW <= 255) )
neighboringPixels.add(imageMatrix[h][minW]);
if ( (maxW != w) && (maxW >= 0) )
neighboringPixels.add(imageMatrix[h][maxW]);
}
if ((nextH >= 0) && (nextH <= 255))
for (int i = minW; i <= maxW; i++)
neighboringPixels.add(imageMatrix[nextH][i]);
最坏情况2+2+4+6+2+4 = 20个条件
进一步优化:
条件 if ( (a>=0) && (a<=255) )
可以优化为 if ( (a&~0xff) != 0)
但它仅适用于 [0-255]
范围