C# 改进算法提高扫描速度——从文件中扫描图像
我的代码在这里工作,但需要几秒钟的时间,而对于较大的文件,这需要更长的时间。我想知道是否有人可以看看我的代码,并提出任何有助于加快速度的改进建议 目的: 这是扫描pdf文件并搜索二维码的位图图像,它将返回二维码(解码)C# 改进算法提高扫描速度——从文件中扫描图像,c#,algorithm,image-processing,bitmap,C#,Algorithm,Image Processing,Bitmap,我的代码在这里工作,但需要几秒钟的时间,而对于较大的文件,这需要更长的时间。我想知道是否有人可以看看我的代码,并提出任何有助于加快速度的改进建议 目的: 这是扫描pdf文件并搜索二维码的位图图像,它将返回二维码(解码) 您可以将GetFiles与以下类型一起使用: string[ ] files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories ); 有几件事可以尝试: 按照Carra的建议,按扩展名过滤文件
您可以将GetFiles与以下类型一起使用:
string[ ] files = Directory.GetFiles ( path, "*.png", SearchOption.AllDirectories );
有几件事可以尝试:
QRCodeDecoder
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();
}
但我真的不认为它能解决您的问题,这只是一些小的增强,您的延迟必须在
QRCODECODECODE
和QRCODEBITMAPAGE
类中的某个地方,特别是在decode
方法中,您应该尝试更好地理解它们,然后找出它在内部做什么,这样你就可以改进你的代码。在代码中,你通过一切都可以。问题一定出在QRCODECODE.decode函数中。如果通过Bitmap.GetPixel函数逐像素扫描图像,将浪费大量时间。更好的方法是使用不安全的代码并将位图转换为位图数据。根据您的评论,如果您只需要处理图像的左上角,则可以使用位图.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));
}
}
private void ScanQRPdf(字符串图像路径)
{
foreach(DecodeAllImagesInFolder(imagePath)中的var decodedString)
{
rtbpdfData.Text+=解码字符串+“\n”;
}
}
私有静态IEnumerable DecodeAllImagesInFolder(字符串图像路径)
{
foreach(Directory.GetFiles(imagePath,*.png)中的var项)
{
使用(位图b=新位图(图像路径))
{
左上角(b)的收益率;
}
}
}
私有静态字符串DecodeTopLeftCorner(位图)
{
var rect=新矩形(0,0,100,100);
使用(var topLeft=bitmap.Clone(rect、bitmap.PixelFormat))
{
返回新的QRCODECODECODE().decode(新的QRCodeBitmapImage(左上));
}
}
慢代码可能在QRCODECODE
类中。从这里你可以做的不多。问问你自己:解码器是否处理了你的位图
s?1建议:删除catch{}
。你能将链接发布到qrcodecoder
源代码吗?(我假设您正在使用O/S库)获取探查器。它会告诉你瓶颈在哪里。猜测通常是浪费时间。我怀疑这是瓶颈。你是对的,这可能是一个小的改进,取决于文件的数量。但瓶颈可能在解码器中,我们看不到这一部分。我不认为在没有评测的情况下应该提出这样的建议。在这种情况下,我非常确定decode
方法至少占用了95%的执行时间。我刚刚尝试过,但是仍然有点慢。我想知道我是否可以只扫描/检查页面的一个角落以查找二维码,如果这样可以缩短时间的话。二维码将始终位于左上角,如果我找不到,我将旋转页面并检查。这听起来是可行的吗?是的,这是可行的,但是如果这是一个开源库,你必须找到如何分割pdf+1,那么GetPixel
可能是OP的最佳选择(除非他/她想设计一个更好的算法)。感谢你的信息-有没有办法只扫描/检查文件的各个角落以获得位图?是的,当然。如果您知道图像的宽度和高度(可以从位图对象获取),则只能扫描角。看看这里:您可以这样更改循环的部分:/(int counter=2;counterdecode
方法可能在找不到代码时抛出此异常,但我不能不看它的源代码就知道。我看到了,我正在做一些修改和查看。我也刚刚想到。因为我只查看用户传入的单个文件,所以我是否仍然需要有一个目录才能获取所有文件?我不能只用那个文件吗?@BB987:当然可以,为什么不能?如果您已经知道文件名,则无需使用Directory.GetFiles
。因此,在删除foreach循环并将imagepath插入using语句时,是否可以保存<代码>使用(位图b=新位图(图像路径)?
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));
}
}