4

ここでの私のコードは機能しますが、数秒長くかかり、ファイルが大きいほど時間がかかります。誰かが私が持っているものを調べて、これをより速くするのに役立つ何らかの改善を提案できるかどうか知りたいと思いました。

目的:

これは、PDFファイルをスキャンしてQRコードのビットマップ画像を検索することで、そのコードを返します(デコード)

private void ScanQRPdf(string imagePath)
    {
        foreach (var item in Directory.GetFiles(imagePath))
        {
            if (Path.GetExtension(item).ToLower() == ".png")
            {
                Bitmap b = new Bitmap(imagePath);
                try
                {
                    QRCodeDecoder decoder = new QRCodeDecoder();
                    String decodedString = decoder.decode(new QRCodeBitmapImage(b));
                    rtbpdfData.Text += decodedString + "\n";
                }
                catch (Exception ex)
                {
                }
            }
        }
    }

 static void AddQRTag(PdfSharp.Drawing.XGraphics gfx, int xPosition, int yPosition, string QRdata, string HRdata)
    {
        gfx.DrawRectangle(XBrushes.White, xPosition, yPosition, xPosition + 55, yPosition + 85);

        PdfSharp.Drawing.XImage xImage =
            PdfSharp.Drawing.XImage.FromGdiPlusImage(BuildQR(QRdata.ToUpper(), 3,
                                            QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC, 2, QRCodeEncoder.ERROR_CORRECTION.M));
        gfx.DrawImage(xImage, xPosition + 5, yPosition + 5, xImage.PixelWidth * .8, xImage.PixelWidth * .8);


        XFont font = new XFont("OCR B", 6);
        XTextFormatter tf = new XTextFormatter(gfx);
        tf.Alignment = XParagraphAlignment.Left;


        XRect layout = new XRect(xPosition + 5, yPosition + 55, 55, 30);
        tf.DrawString(HRdata.ToUpper(), font, XBrushes.Black, layout, XStringFormats.TopLeft);
    }
4

4 に答える 4

3

すべてを過ぎたコードでは問題ありません。問題は QRCodeDecoder.decode 関数にあるはずです。Bitmap.GetPixel 関数を使用して画像をピクセル単位でスキャンすると、多くの時間が浪費されます。より良い方法は、安全でないコードを使用して、ビットマップを BitmapData に変換することです。

于 2013-02-28T14:28:52.693 に答える
2

コメントに基づいて、画像の左上隅のみを処理する必要がある場合は、を使用して画像のその部分を抽出できますBitmap.Clone

その場合、コードを次のようにリファクタリングします。

private void ScanQRPdf(string imagePath)
{
    foreach (var decodedString in DecodeAllImagesInFolder(imagePath))
    {
        rtbpdfData.Text += decodedString + "\n";
    }
}

private static IEnumerable<string> DecodeAllImagesInFolder(string imagePath)
{
    foreach (var item in Directory.GetFiles(imagePath, "*.png"))
    {
        using (Bitmap b = new Bitmap(imagePath))
        {
            yield return DecodeTopLeftCorner(b);
        }
    }
}

private static string DecodeTopLeftCorner(Bitmap bitmap)
{
    var rect = new Rectangle(0, 0, 100, 100);
    using (var topLeft = bitmap.Clone(rect, bitmap.PixelFormat))
    {
        return new QRCodeDecoder().decode(new QRCodeBitmapImage(topLeft));
    }
}
于 2013-02-28T16:21:22.017 に答える
2

試してみるいくつかのこと:

  1. Carraが提案するように、拡張子でファイルをフィルタリングします
  2. QRCodeDecoder一度だけ宣言してインスタンス化する
  3. を使用してテキストを追加し、StringBuilder一度だけ割り当てます

それは次のようなものです:

private void ScanQRPdf(string imagePath)
{
    var files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories );

    QRCodeDecoder decoder = new QRCodeDecoder();

    StringBuilder sb = new StringBuilder();

    foreach (var item in files)
    {

            Bitmap b = new Bitmap(imagePath);
            try
            {
                String decodedString = decoder.decode(new QRCodeBitmapImage(b));

                sb.AppendLine(decodedString);
            }
            catch (Exception ex)
            {
            }

    }

    rtbpdfData.Text = sb.ToString();
}

しかし、それがあなたの問題を解決するとは本当に思いません。それはすべてマイナーな機能強化であり、遅延はQRCodeDecoderandQRCodeBitmapImageクラス内のどこかにある必要がありdecodeます。コードを改善できます。

于 2013-02-28T14:25:00.980 に答える
1

次のタイプで GetFiles を使用できます。

string[ ] files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories ); 
于 2013-02-28T14:21:38.437 に答える