【问题标题】:making an instance of a class only in particular iterations of a for loop仅在 for 循环的特定迭代中创建类的实例
【发布时间】:2014-11-03 17:41:28
【问题描述】:

下面的代码似乎不起作用。该函数的目标是将位图(LockBitmap)划分为 8 x 8 像素的块,并将它们存储在一个数组中。

我编写了一个 MotionBlock 类,其中包含块的 X 和 Y 分量以及包含位图值的 8x8 整数。

函数循环遍历 lbmp 的 width 和 height 属性。每次 i mod 8 为 0 且 j mod 8 为 0 时,都应创建一个新的 motionBlock 实例,并分配 X 和 Y 属性。对于其他迭代,应为灰度值的 int 数组分配一个值。

在分配最后一个像素的值后,应该将 MotionBlock 复制到数组中,并且应该在下一次迭代中制作一个新的 MotionBlock(应该再次两次 0 mod 8),重新开始过程直到循环结束。

问题:数组似乎是空的。在下面的代码中,我尝试在 for 循环之外创建 MotionBlock 的实例,在 for 循环中使用它,并在每 8x8 像素将其写入数组之后,然后在之后的迭代中覆盖运动块。

我认为这不是正确的方法,但是当我在 if 语句中创建 motionBlock 的实例时,我无法在 if 语句之外使用它,所以我一直在寻找一种方法来制作一个实例,使用它进行几次迭代,将其写入一个数组,然后继续一个新实例。

public static MotionBlock[] getImageBlocks(LockBitmap lbmp)
{
    int x = lbmp.Width / 8;
    int y = lbmp.Height / 8;
    int surface = x * y;

    MotionBlock[] blocks = new MotionBlock[surface];
    MotionBlock block = new MotionBlock();

    int teller = 0;

    for (int i = 0; i < lbmp.Width; i++)
    {
        for (int j = 0; j < lbmp.Height; j++)
        {
            if (i % 8 == 0 && j % 8 == 0)
            {
                block.X = i;
                block.Y = j;
            }

            int r = i % 8;
            int k = j % 8;

            block.GrayValues[r, k] = lbmp.GetPixel(i, j).R;
            Console.WriteLine(block.grayValues[r, k]);

            if (i % 8 == 7 && i % 8 == 7)
            {
                blocks[teller] = block;
            }

            teller++;
        }

        teller++;
    }

    return blocks;
}

【问题讨论】:

  • 您需要告诉我们它是如何不工作的吗?您期望什么,实际得到什么?
  • @ChrisDunaway 好的会编辑
  • 我不认为你想要第二个teller++
  • block.X 和 block.Y 属性代表什么?以第一块为例应该(block.X, block.Y)等于(0, 0)或者(7, 7)
  • @Jonesy 是的,谢谢。

标签: c# for-loop logic instance


【解决方案1】:

我认为您需要在x 和y 为0 时声明一个新块,否则您会不断更新相同的block。此外,您不需要在 Height 循环结束时将索引增加两次。最后,为了便于阅读,使用比i、j、r 和k 更具描述性的变量名称可能会有所帮助。

这里是修改后的代码(主要变化是blockX和blockY为0时添加了block = new MotionBlock):

public static MotionBlock[] getImageBlocks(LockBitmap lockBitmap)
{
    int surface = (lockBitmap.Width / 8) * (lockBitmap.Height / 8);

    MotionBlock[] blocks = new MotionBlock[surface];
    MotionBlock block = new MotionBlock();

    int blockIndex = 0;

    for (int imageX = 0; imageX < lockBitmap.Width; imageX++)
    {
        for (int imageY = 0; imageY < lockBitmap.Height; imageY++)
        {
            // Get the block-level X and Y coordinates
            int blockX = imageX % 8;
            int blockY = imageY % 8;

            // If we are at the start of a new block, create it
            if (blockX == 0 && blockY == 0)
            {
                block = new MotionBlock {X = imageX, Y = imageY};
            }

            // Set the gray values of the current block and output to console
            block.GrayValues[blockX, blockY] = lockBitmap.GetPixel(imageX, imageY).R;
            Console.WriteLine(block.grayValues[blockX, blockY]);

            // If we are at the end of a block, save it to our array
            if (blockX == 7 && blockY == 7)
            {
                blocks[blockIndex] = block;
            }

            // Increment our block array index
            blockIndex++;
        }
    }

    return blocks;
}

【讨论】:

  • 您的代码也不起作用,这正是问题所在,您无法访问 if 语句之外的块,因为您在 if 语句中实例化了它。
  • 是的,你可以。声明在 for 循环之外,因此它在 for 循环内和所有 if 语句内都有范围(请注意,我没有创建 new 变量,我只是重新分配 现有的一个)...
  • 事实上,它可以在第二个 for 循环中声明,代码仍然可以正常工作。你有例外吗?如果是这样,您可以发布它(以及行号)吗?
  • 这是我收到的错误的链接:link
  • 啊,好的。这是因为我最初没有分配它(逻辑上我知道它会被分配,但显然编译器没有看到)。如果你在声明时添加一个赋值,那应该可以解决它:MotionBlock block = new MotionBlock(); 我也会更新示例。
【解决方案2】:

我相信您在这里寻找的只是一个 continue 语句。

据我了解,您只是想在条件满足时忽略给定的循环迭代

"i mod 8 为 0,j mod 8 为 0"

不满意。因此我建议在 if 块的末尾添加 continue

if (i % 8 == 0 && j % 8 == 0)
    {
        block.X = i;
        block.Y = j;
    }
else
    continue;

【讨论】:

  • 不,我不想忽略它,我想做点别的。让我试着解释一下:
  • 不,我不想忽略它,我想做点别的。让我试着解释一下:' if (i % 8 == 0 && j % 8 == 0) { MotionBlock block = new MotionBlock();块.X = i;块.Y = j; } int r = i % 8;诠释 k = j % 8;诠释 r = 我 % 8; block.GrayValues[r, k] = lbmp.GetPixel(i, j).R; Console.WriteLine(block.grayValues[r, k]); if (i % 8 == 7 && i % 8 == 7) { blocks[teller] = block; } 柜员++; '
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 2014-08-30
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多