Program.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. using Microsoft.SqlServer.Server;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using ZXing;
  10. using ZXing.Common;
  11. using static System.Net.Mime.MediaTypeNames;
  12. namespace DumaTest
  13. {
  14. internal class Program
  15. {
  16. static void Main(string[] args)
  17. {
  18. //string result = "";
  19. //try
  20. //{
  21. // result = CodeDict[in0];
  22. //}
  23. //catch
  24. //{
  25. // char[] charArray = in0.ToCharArray();
  26. // Array.Reverse(charArray);
  27. // string reversed = new string(charArray);
  28. // result = CodeDict[reversed];
  29. //}
  30. //out0 = result;
  31. //string imagePath = @"D:\work\TEST\Image_20250802111433217.bmp";
  32. //// 诊断图像
  33. //DiagnoseBarcode(imagePath);
  34. //// 尝试高级解码
  35. //var result = DecodeBarcodeAdvanced(imagePath);
  36. //if (result != null)
  37. //{
  38. // Console.WriteLine($"识别成功: {result.Text}");
  39. // Console.WriteLine($"条码格式: {result.BarcodeFormat}");
  40. //}
  41. //else
  42. //{
  43. // Console.WriteLine("未能识别条码,请检查图像质量或尝试其他方法");
  44. //}
  45. //Dictionary<string,string> keyValues = new Dictionary<string, string>();
  46. //keyValues.Add("key1", "value1");
  47. //string result = keyValues["key1"];
  48. //Console.WriteLine(result);
  49. Console.ReadKey();
  50. }
  51. public static Result DecodeBarcode(string imagePath)
  52. {
  53. try
  54. {
  55. // 确保使用正确的图像格式加载
  56. using (var bitmap = new Bitmap(imagePath))
  57. {
  58. var barcodeReader = new BarcodeReader
  59. {
  60. Options = new ZXing.Common.DecodingOptions
  61. {
  62. TryHarder = true, // 更努力地尝试解码
  63. PureBarcode = false
  64. }
  65. };
  66. return barcodeReader.Decode(bitmap);
  67. }
  68. }
  69. catch (Exception ex)
  70. {
  71. Console.WriteLine($"解码错误: {ex.Message}");
  72. return null;
  73. }
  74. }
  75. public static void DiagnoseBarcode(string imagePath)
  76. {
  77. Console.WriteLine($"正在诊断图像: {imagePath}");
  78. try
  79. {
  80. using (var bitmap = new Bitmap(imagePath))
  81. {
  82. Console.WriteLine($"图像尺寸: {bitmap.Width} x {bitmap.Height}");
  83. Console.WriteLine($"像素格式: {bitmap.PixelFormat}");
  84. // 检查图像是否为空或太小
  85. if (bitmap.Width < 10 || bitmap.Height < 10)
  86. {
  87. Console.WriteLine("警告: 图像太小");
  88. return;
  89. }
  90. var reader = new BarcodeReader();
  91. // 尝试不同的配置
  92. var configs = new[]
  93. {
  94. new { Name = "默认配置", TryHarder = false, PureBarcode = false },
  95. new { Name = "TryHarder", TryHarder = true, PureBarcode = false },
  96. new { Name = "PureBarcode", TryHarder = false, PureBarcode = true },
  97. new { Name = "TryHarder+PureBarcode", TryHarder = true, PureBarcode = true }
  98. };
  99. foreach (var config in configs)
  100. {
  101. reader.Options.TryHarder = config.TryHarder;
  102. reader.Options.PureBarcode = config.PureBarcode;
  103. var result = reader.Decode(bitmap);
  104. Console.WriteLine($"{config.Name}: {(result != null ? "成功" : "失败")}");
  105. if (result != null)
  106. {
  107. Console.WriteLine($" 内容: {result.Text}");
  108. Console.WriteLine($" 格式: {result.BarcodeFormat}");
  109. return;
  110. }
  111. }
  112. Console.WriteLine("所有配置都未能识别条码");
  113. }
  114. }
  115. catch (Exception ex)
  116. {
  117. Console.WriteLine($"诊断过程中发生错误: {ex.Message}");
  118. }
  119. }
  120. public static Result DecodeBarcodeAdvanced(string imagePath)
  121. {
  122. var barcodeReader = new BarcodeReader
  123. {
  124. Options = new DecodingOptions
  125. {
  126. // 尝试所有可能的格式
  127. PossibleFormats = new List<BarcodeFormat>
  128. {
  129. BarcodeFormat.QR_CODE,
  130. BarcodeFormat.CODE_128,
  131. BarcodeFormat.CODE_39,
  132. BarcodeFormat.EAN_13,
  133. BarcodeFormat.UPC_A,
  134. BarcodeFormat.UPC_E,
  135. BarcodeFormat.EAN_8,
  136. BarcodeFormat.DATA_MATRIX,
  137. BarcodeFormat.PDF_417,
  138. BarcodeFormat.AZTEC
  139. },
  140. TryHarder = true,
  141. PureBarcode = false,
  142. }
  143. };
  144. try
  145. {
  146. using (var bitmap = new Bitmap(imagePath))
  147. {
  148. try
  149. {
  150. var result = barcodeReader.Decode(bitmap);
  151. if (result != null)
  152. return result;
  153. }
  154. catch (NullReferenceException nullEx)
  155. {
  156. Console.WriteLine($"空引用异常: {nullEx.Message}");
  157. // 记录更详细的堆栈跟踪
  158. Console.WriteLine($"堆栈跟踪: {nullEx.StackTrace}");
  159. return null;
  160. }
  161. catch (Exception ex)
  162. {
  163. Console.WriteLine($"解码异常: {ex.Message}");
  164. return null;
  165. }
  166. // 如果失败,尝试其他方法
  167. return TryAlternativeMethods(bitmap, barcodeReader);
  168. }
  169. }
  170. catch (Exception ex)
  171. {
  172. Console.WriteLine($"解码异常: {ex.Message}");
  173. return null;
  174. }
  175. }
  176. private static Result TryAlternativeMethods(Bitmap bitmap, BarcodeReader reader)
  177. {
  178. // 方法1: 转换为灰度图
  179. var grayscaleBitmap = ConvertToGrayscale(bitmap);
  180. var result = reader.Decode(grayscaleBitmap);
  181. if (result != null) return result;
  182. // 方法2: 调整图像大小
  183. var resizedBitmap = ResizeImage(bitmap, bitmap.Width *2, bitmap.Height *2);
  184. result = reader.Decode(resizedBitmap);
  185. if (result != null) return result;
  186. // 方法3: 旋转图像尝试不同角度
  187. for (int i = 0; i < 4; i++)
  188. {
  189. var rotatedBitmap = RotateImage(bitmap, i * 90);
  190. result = reader.Decode(rotatedBitmap);
  191. if (result != null) return result;
  192. }
  193. return null;
  194. }
  195. private static Bitmap ConvertToGrayscale(Bitmap original)
  196. {
  197. var grayscale = new Bitmap(original.Width, original.Height);
  198. using (var g = Graphics.FromImage(grayscale))
  199. {
  200. var colorMatrix = new ColorMatrix(
  201. new float[][]
  202. {
  203. new float[] {.3f, .3f, .3f, 0, 0},
  204. new float[] {.59f, .59f, .59f, 0, 0},
  205. new float[] {.11f, .11f, .11f, 0, 0},
  206. new float[] {0, 0, 0, 1, 0},
  207. new float[] {0, 0, 0, 0, 1}
  208. });
  209. using (var attributes = new ImageAttributes())
  210. {
  211. attributes.SetColorMatrix(colorMatrix);
  212. g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
  213. 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
  214. }
  215. }
  216. return grayscale;
  217. }
  218. private static Bitmap ResizeImage(Bitmap original, int width, int height)
  219. {
  220. var resized = new Bitmap(width, height);
  221. using (var g = Graphics.FromImage(resized))
  222. {
  223. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  224. g.DrawImage(original, 0, 0, width, height);
  225. }
  226. return resized;
  227. }
  228. private static Bitmap RotateImage(Bitmap original, float angle)
  229. {
  230. var rotated = new Bitmap(original.Width, original.Height);
  231. using (var g = Graphics.FromImage(rotated))
  232. {
  233. g.TranslateTransform(original.Width / 2f, original.Height / 2f);
  234. g.RotateTransform(angle);
  235. g.TranslateTransform(-original.Width / 2f, -original.Height / 2f);
  236. g.DrawImage(original, new Point(0, 0));
  237. }
  238. return rotated;
  239. }
  240. public static Result DecodeLargeBarcode(string imagePath)
  241. {
  242. using (var originalBitmap = new Bitmap(imagePath))
  243. {
  244. Console.WriteLine($"原始图像尺寸: {originalBitmap.Width} x {originalBitmap.Height}");
  245. // 方法1: 调整尺寸
  246. var result = DecodeBarcodeWithResizing(imagePath);
  247. if (result != null) return result;
  248. // 方法2: 裁剪识别
  249. result = DecodeWithCropping(originalBitmap);
  250. if (result != null) return result;
  251. // 方法3: 综合处理
  252. result = DecodeWithComprehensiveApproach(originalBitmap);
  253. if (result != null) return result;
  254. }
  255. return null;
  256. }
  257. private static Result DecodeWithComprehensiveApproach(Bitmap original)
  258. {
  259. var reader = new BarcodeReader
  260. {
  261. Options = new ZXing.Common.DecodingOptions
  262. {
  263. TryHarder = true,
  264. PureBarcode = false,
  265. PossibleFormats = new List<BarcodeFormat>
  266. {
  267. BarcodeFormat.CODE_128,
  268. BarcodeFormat.CODE_39,
  269. BarcodeFormat.EAN_13,
  270. BarcodeFormat.UPC_A
  271. }
  272. }
  273. };
  274. // 组合多种策略
  275. var strategies = new Func<Bitmap, Bitmap>[]
  276. {
  277. // 原始图像
  278. bmp => new Bitmap(bmp),
  279. // 调整尺寸
  280. bmp => ResizeForBarcodeRecognition(bmp, 800),
  281. bmp => ResizeForBarcodeRecognition(bmp, 1200),
  282. // 裁剪
  283. bmp => CropCenter(bmp, 0.8),
  284. bmp => CropCenter(bmp, 0.6),
  285. // 先裁剪再调整尺寸
  286. bmp => ResizeForBarcodeRecognition(
  287. CropCenter(bmp, 0.7), 1000)
  288. };
  289. foreach (var strategy in strategies)
  290. {
  291. try
  292. {
  293. using (var processed = strategy(original))
  294. {
  295. var result = reader.Decode(processed);
  296. if (result != null)
  297. {
  298. Console.WriteLine("使用综合策略识别成功");
  299. return result;
  300. }
  301. }
  302. }
  303. catch (Exception ex)
  304. {
  305. Console.WriteLine($"策略执行失败: {ex.Message}");
  306. }
  307. }
  308. return null;
  309. }
  310. /// <summary>
  311. /// 调整图像尺寸以优化条码识别
  312. /// </summary>
  313. /// <param name="originalImage">原始图像</param>
  314. /// <param name="maxDimension">最大尺寸</param>
  315. /// <returns>调整后的图像</returns>
  316. public static Bitmap ResizeForBarcodeRecognition(Bitmap originalImage, int maxDimension = 800)
  317. {
  318. // 如果图像尺寸已经合适,则直接返回
  319. if (originalImage.Width <= maxDimension && originalImage.Height <= maxDimension)
  320. {
  321. return originalImage;
  322. }
  323. // 计算缩放比例
  324. double scale = Math.Min(maxDimension / (double)originalImage.Width,
  325. maxDimension / (double)originalImage.Height);
  326. int newWidth = (int)(originalImage.Width * scale);
  327. int newHeight = (int)(originalImage.Height * scale);
  328. var resizedImage = new Bitmap(newWidth, newHeight);
  329. using (var graphics = Graphics.FromImage(resizedImage))
  330. {
  331. graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  332. graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight);
  333. }
  334. return resizedImage;
  335. }
  336. /// <summary>
  337. /// 尝试多种尺寸识别条码
  338. /// </summary>
  339. public static Result DecodeBarcodeWithResizing(string imagePath)
  340. {
  341. using (var originalBitmap = new Bitmap(imagePath))
  342. {
  343. var reader = new BarcodeReader
  344. {
  345. Options = new ZXing.Common.DecodingOptions
  346. {
  347. TryHarder = true,
  348. PureBarcode = false
  349. }
  350. };
  351. // 尝试不同尺寸
  352. int[] sizes = { 0, 800, 1200, 1600 }; // 0 表示原始尺寸
  353. foreach (int size in sizes)
  354. {
  355. using (Bitmap bitmap = size == 0 ?
  356. new Bitmap(originalBitmap) :
  357. ResizeForBarcodeRecognition(originalBitmap, size))
  358. {
  359. var result = reader.Decode(bitmap);
  360. if (result != null)
  361. {
  362. Console.WriteLine($"在尺寸 {size} 下识别成功");
  363. return result;
  364. }
  365. }
  366. }
  367. }
  368. return null;
  369. }
  370. /// <summary>
  371. /// 裁剪图像中心区域以优化识别
  372. /// </summary>
  373. public static Bitmap CropCenter(Bitmap original, double cropRatio = 0.8)
  374. {
  375. int cropWidth = (int)(original.Width * cropRatio);
  376. int cropHeight = (int)(original.Height * cropRatio);
  377. int x = (original.Width - cropWidth) / 2;
  378. int y = (original.Height - cropHeight) / 2;
  379. var cropped = new Bitmap(cropWidth, cropHeight);
  380. using (var graphics = Graphics.FromImage(cropped))
  381. {
  382. graphics.DrawImage(original,
  383. new Rectangle(0, 0, cropWidth, cropHeight),
  384. new Rectangle(x, y, cropWidth, cropHeight),
  385. GraphicsUnit.Pixel);
  386. }
  387. return cropped;
  388. }
  389. /// <summary>
  390. /// 多区域裁剪识别
  391. /// </summary>
  392. public static Result DecodeWithCropping(Bitmap originalBitmap)
  393. {
  394. var reader = new BarcodeReader
  395. {
  396. Options = new ZXing.Common.DecodingOptions
  397. {
  398. TryHarder = true
  399. }
  400. };
  401. // 尝试不同裁剪比例
  402. double[] cropRatios = { 1.0, 0.9, 0.8, 0.7, 0.6 };
  403. foreach (double ratio in cropRatios)
  404. {
  405. using (var cropped = ratio >= 1.0 ?
  406. new Bitmap(originalBitmap) :
  407. CropCenter(originalBitmap, ratio))
  408. {
  409. var result = reader.Decode(cropped);
  410. if (result != null)
  411. {
  412. Console.WriteLine($"裁剪比例 {ratio} 识别成功");
  413. return result;
  414. }
  415. }
  416. }
  417. return null;
  418. }
  419. }
  420. }