【问题标题】:creating a loop instead of repeating if statements创建循环而不是重复 if 语句
【发布时间】:2013-03-08 23:23:27
【问题描述】:

我无法解决这个问题,并希望对此有一些意见。因此,我正在阅读一份扫描的 PDF 文档,其中包含一个二维码,该二维码始终位于文档的左上角。

由于扫描文件可能会改变文档的方向,我正在检查文档的左上角是否有二维码,如果没有,我将旋转文档并再次检查左上角。这样做的目的是因为 QR 码位于左上角,因此该文档的格式符合我的要求。

如何更改我的以下代码,以便它获取 QR 码的文档检查 - 如果未找到,请再次旋转整个文档检查并继续直到找到 QR 码。我也应该循环旋转 90 而不是 90 - 180 - 270。

using (var fullImg = new Bitmap(workGif))
{
    var bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, 375, 375), fullImg.PixelFormat);
    Bitmap result = fullImg;
    if (Process(bandImg) == null)
    {
        fullImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
        bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
        if (Process(bandImg) == null)
        {
            fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
            bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);

            if (Process(bandImg) == null)
            {
                fullImg.RotateFlip(RotateFlipType.Rotate180FlipNone);
                bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
            }
         }
    }
    bandImg.Save(@"C:\NewImageTest.png");
    string QRinfo = Process(bandImg);
    MessageBox.Show(QRinfo);
}

处理方法 我在这个方法中通过图片来查看是否有二维码可以读取。

public string Process(Bitmap bitmap)
{
    var reader = new com.google.zxing.qrcode.QRCodeReader();

    try
    {
        LuminanceSource source = new RGBLuminanceSource(bitmap, bitmap.Width, bitmap.Height);
        var binarizer = new HybridBinarizer(source);
        var binBitmap = new BinaryBitmap(binarizer);
        return reader.decode(binBitmap).Text;
    }
    catch (Exception e)
    {
        return null;
    }
}

【问题讨论】:

  • 什么是result,它来自哪里?
  • @cdhowie 错过了放入 - 结果是整个文件页面的图像。

标签: c# for-loop while-loop


【解决方案1】:

这样的东西不适合你吗?文档只有四种可能的方向,因此您最多必须循环四次。每个循环将图像旋转 90 度。一旦您确定 QR 码位于左上角,您就可以退出循环 break。然后你可以处理二维码或做任何你想做的事情。

public void Do(string workGif)
{
    // ...
    string qrInfo;
    using (var fullImg = new Bitmap(workGif))
    {
        for (int i = 0; i < 4; i++)
        {
            // Does the image contain a QR code?
            qrInfo = Process(fullImg);
            if (qrInfo = null)
                // No QR code found. Rotate the image.
                fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
            else
                // QR code found. Break out of the loop.
                break;
        }
        if (qrInfo == null)
        {
            throw new InvalidOperationException(
                "The document contains no QR code.");
        }
    }
    MessageBox.Show(qrInfo);
    // ...
}

您可以将获取源图像角落图像的代码移动到Process方法。

private Image GetCornerImage(Image sourceImage)
{
    return sourceImage.Clone(new Rectangle(0, 0, 375, 375), sourceImage.PixelFormat);
}

public string Process(Bitmap bitmap)
{
    var cornerImg = GetCornerImage(bitmap);

    var reader = new com.google.zxing.qrcode.QRCodeReader();
    LuminanceSource source = new RGBLuminanceSource(
        cornerImg, cornerImg.Width, cornerImg.Height);
    var binarizer = new HybridBinarizer(source);
    var binBitmap = new BinaryBitmap(binarizer);
    return reader.decode(binBitmap).Text;
}

【讨论】:

  • 我刚试过这个,一切都说得通,但我意识到我的var bandImg 只看特定的角落,旋转时它会旋转那个角落而不是整个页面,所以我在 forloop 中进行了更改到fullImage.RotateFlip...,但经过测试,它仅在二维码已经采用正确格式(左上角)时才有效
  • 对于if(HasProperQRCode(bandImg)),我实际上正在使用Process(bandImg),我在上面发布了它的代码。如果存在,我用它来读取二维码。
  • 非常感谢您的帮助。当我传入一个二维码不在左上角的文件时,我仍然收到错误消息。但是如果我传入一个二维码位于左上角的文件,它就可以工作。我会处理这个,看看我能改变什么
  • @Amina 您可能会从您正在使用的QRCodeReader 中得到一个错误。阅读文档并了解,例如,是否有一种方法可以在没有二维码的情况下使用它而无需捕获异常。也许是一个返回布尔值的trydecode 方法?
  • 我现在会调查一下 - 谢谢。我将调试并查看发生了什么,因为它曾经与我拥有的所有 if 语句一起使用。
【解决方案2】:

这应该可以正常工作;

using (var fullImg = new Bitmap(workGif))
{
    var bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, 375, 375), fullImg.PixelFormat);
    int i = 0;
    while(Process(bandImg) == null)
    {
        if (i == 1)
            fullImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
        else if (i == 2)
            fullImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
        else if (i== 3)
            fullImg.RotateFlip(RotateFlipType.Rotate180FlipNone);

            /*
                 Another way in which Rotation Degree can be done
                 First time it rotate by 270, then by 180 & then by 90
                 int i must be initialized with 1
                 int degree_to_rotate = 360 - ((4 - i) * 90)
            */

        bandImg = fullImg.Clone(new System.Drawing.Rectangle(0, 0, result.Width, result.Height), fullImg.PixelFormat);
        i++;
    }
    bandImg.Save(@"C:\NewImageTest.png");
    string QRinfo = Process(bandImg);
    MessageBox.Show(QRinfo);
}

【讨论】:

  • 好的,这样我就明白了 - Process(bandImg) 是用于检查是否有要读取的二维码的方法。如果不是,则应旋转页面,并再次将新的旋转页面传递给 Process() 以进行检查。如果while(Process(bandImg) != null) 则它打破循环并且如果它为空则不旋转。应该是while(Process(bandImg) == null) 吗?
  • @Amina - 抱歉,匆忙看错了代码,是的,应该是==
  • 由于某种奇怪的原因,它适用于 qr 码已经在正确位置(左上角)的文件,如果我传入一个 qr 码位于右下角的文件,它会给我一个错误
【解决方案3】:

如果您在每次轮换中都进行相同的检查,则没有理由不使用循环。只需确保跟踪执行的旋转次数,否则您将陷入无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2021-04-30
    相关资源
    最近更新 更多