Nxing 生成条码图片失真,打印出来也失真。求助!!!

__东林 2025-03-06 09:39:23

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Drawing.Printing;
using ZXing;
using ZXing.QrCode;
// 添加此命名空间引用
using ZXing.Windows.Compatibility;
using ZXing.Common;
using System.Drawing.Drawing2D;

namespace BarcodePrinter
{
    class Program
    {
        // 打印机参数配置
        const int DPI = 300; // 常见标签打印机分辨率(300/600可选)
        const float PAPER_WIDTH_MM = 100f;
        const float PAPER_HEIGHT_MM = 50f;
        const int BARCODE_HEIGHT_RATIO = 60; // 条码占标签高度的百分比
        static void Main()
        {
            string sourceFolder = @"D:\SourceFolder"; // 指定源文件夹
            string destinationFolder = @"D:\DestinationFolder"; // 指定目标文件夹
            string logFilePath = @"D:\Log\BarcodeLog.txt"; // 指定日志文件路径
            string barcodeImageFolder = @"D:\BarcodeImages"; // 指定条形码图像保存的文件夹

            try
            {
                // 确保目标文件夹存在
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }

                // 确保日志文件夹存在
                string logFolder = Path.GetDirectoryName(logFilePath);
                if (!Directory.Exists(logFolder))
                {
                    Directory.CreateDirectory(logFolder);
                }

                // 确保条形码图像保存文件夹存在
                if (!Directory.Exists(barcodeImageFolder))
                {
                    Directory.CreateDirectory(barcodeImageFolder);
                }

                // 获取源文件夹中的所有 XML 文件
                string[] xmlFiles = Directory.GetFiles(sourceFolder, "*.xml");

                if (xmlFiles.Length == 0)
                {
                    LogError(logFilePath, null, new FileNotFoundException($"未在 {sourceFolder} 中找到任何 XML 文件。"));
                    return;
                }

                foreach (string xmlFile in xmlFiles)
                {
                    try
                    {
                        // 读取 XML 文件内容
                        var (barcodeText, additionalText) = ReadBarcodeTextFromXml(xmlFile);

                        // 生成条形码图像
                        Bitmap barcodeImage = GenerateBarcode(barcodeText, additionalText);

                        // 保存条形码图像到指定文件夹
                        string barcodeImagePath = SaveBarcodeImage(barcodeImage, barcodeImageFolder, Path.GetFileNameWithoutExtension(xmlFile));

                        // 打印条形码
                        PrintBarcode(barcodeImage, barcodeText);

                        // 记录日志
                        LogSuccess(logFilePath, xmlFile);

                        // 移动处理后的 XML 文件
                        MoveXmlFile(xmlFile, destinationFolder);
                    }
                    catch (Exception ex)
                    {
                        // 记录错误日志
                        LogError(logFilePath, xmlFile, ex);
                    }
                }
            }
            catch (Exception ex)
            {
                LogError(logFilePath, null, ex);
            }
        }

        static (string barcodeText, string additionalText) ReadBarcodeTextFromXml(string xmlFile)
        {
            try
            {
                XDocument doc = XDocument.Load(xmlFile);
                string barcodeText = doc.Descendants("Code").FirstOrDefault()?.Value;
                string item = doc.Descendants("Item").FirstOrDefault()?.Value;
                string qty = doc.Descendants("Qty").FirstOrDefault()?.Value;
                string lot = doc.Descendants("Lot").FirstOrDefault()?.Value;

                string additionalText = $"Item: {item}\nQty: {qty}\nLot: {lot}";
                return (barcodeText, additionalText);
            }
            catch (Exception ex)
            {
                throw new Exception($"读取 XML 文件 {xmlFile} 时出错: {ex.Message}", ex);
            }
        }

        static Bitmap GenerateBarcode(string barcodeText, string additionalText)
        {
            try
            {
                // 计算像素尺寸(毫米转英寸)
                int widthPx = (int)(PAPER_WIDTH_MM / 25.4 * DPI);
                int heightPx = (int)(PAPER_HEIGHT_MM / 25.4 * DPI);

                // 将条码高度减小一半
                int barcodeHeightPx = (int)(heightPx * 0.6 / 2);

                // 生成高质量条码
                var writer = new BarcodeWriterPixelData
                {
                    Format = BarcodeFormat.CODE_128,
                    Options = new EncodingOptions
                    {
                        Width = widthPx,
                        Height = barcodeHeightPx,
                        Margin = 1,
                        PureBarcode = true
                    }
                };

                var pixelData = writer.Write(barcodeText);

                // 创建高分辨率位图
                Bitmap barcodeBitmap = new Bitmap(pixelData.Width, pixelData.Height, PixelFormat.Format32bppArgb);
                barcodeBitmap.SetResolution(DPI, DPI);

                // 写入像素数据
                BitmapData bitmapData = barcodeBitmap.LockBits(
                    new Rectangle(0, 0, pixelData.Width, pixelData.Height),
                    ImageLockMode.WriteOnly,
                    PixelFormat.Format32bppArgb);

                System.Runtime.InteropServices.Marshal.Copy(
                    pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);

                barcodeBitmap.UnlockBits(bitmapData);

                // 添加文字信息
                return AddTextToBarcode(barcodeBitmap, additionalText, heightPx);
            }
            catch (Exception ex)
            {
                throw new Exception($"生成条码失败: {ex.Message}", ex);
            }
        }

        static Bitmap AddTextToBarcode(Bitmap barcodeImage, string text, int totalHeight)
        {
            Bitmap finalImage = new Bitmap(barcodeImage.Width, totalHeight);
            finalImage.SetResolution(DPI, DPI);

            using (Graphics g = Graphics.FromImage(finalImage))
            {
                g.Clear(Color.White);

                // 向左上方移动条码,这里将条码向左移动条码宽度的 1/10,向上移动条码高度的 1/4
                int barcodeX = -barcodeImage.Width / 10+50;
                int barcodeY = (totalHeight - barcodeImage.Height) / 2 - barcodeImage.Height / 4-40;
                g.DrawImage(barcodeImage, barcodeX, barcodeY);

                // 设置更大的文本字体
                using (Font font = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point))
                using (StringFormat format = new StringFormat
                {
                    Alignment = StringAlignment.Near, // 左对齐
                    LineAlignment = StringAlignment.Near
                })
                {
                    // 在条码下方添加文字,与条码对齐
                    RectangleF textRect = new RectangleF(
                        barcodeX+145,
                        barcodeY + barcodeImage.Height + 20,
                        finalImage.Width,
                        totalHeight - (barcodeY + barcodeImage.Height));

                    g.DrawString(text, font, Brushes.Black, textRect, format);
                }
            }
            return finalImage;
        }

        static string SaveBarcodeImage(Bitmap barcodeImage, string barcodeImageFolder, string fileName)
        {
            try
            {
                string filePath = Path.Combine(barcodeImageFolder, $"{fileName}.png");
                barcodeImage.Save(filePath, ImageFormat.Png);
                return filePath;
            }
            catch (Exception ex)
            {
                throw new Exception($"保存条形码图像到 {barcodeImageFolder} 时出错: {ex.Message}", ex);
            }
        }

        static void PrintBarcode(Bitmap barcodeImage, string barcodeText)
        {
            using (PrintDocument pd = new PrintDocument())
            {
                // 设置打印机参数
                pd.DefaultPageSettings.PrinterSettings.DefaultPageSettings.PaperSize =
                    new PaperSize("Custom",
                        (int)(PAPER_WIDTH_MM / 25.4 * 100), // 转换为百分之一英寸
                        (int)(PAPER_HEIGHT_MM / 25.4 * 100));

                pd.DefaultPageSettings.Landscape = false;
                pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);

                pd.PrintPage += (sender, e) =>
                {
                    // 高质量绘制
                    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                    e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                    // 精确匹配打印区域
                    e.Graphics.DrawImage(
                        barcodeImage,
                        new Rectangle(
                            e.MarginBounds.Left,
                            e.MarginBounds.Top,
                            e.MarginBounds.Width,
                            e.MarginBounds.Height),
                        new Rectangle(0, 0, barcodeImage.Width, barcodeImage.Height),
                        GraphicsUnit.Pixel); 
                };

                pd.Print();
            }
        }

        static void LogSuccess(string logFilePath, string xmlFile)
        {
            string logMessage = $"[{DateTime.Now}] 成功处理文件: {xmlFile}";
            File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
        }

        static void LogError(string logFilePath, string xmlFile, Exception ex)
        {
            string logMessage = $"[{DateTime.Now}] 处理文件 {xmlFile} 时出错: {ex.Message}";
            File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
        }

        static void MoveXmlFile(string xmlFile, string destinationFolder)
        {
            try
            {
                string destinationPath = Path.Combine(destinationFolder, Path.GetFileName(xmlFile));
                File.Move(xmlFile, destinationPath);
            }
            catch (Exception ex)
            {
                LogError(Path.GetDirectoryName(xmlFile), xmlFile, new Exception($"移动 XML 文件 {xmlFile} 到 {destinationFolder} 时出错: {ex.Message}", ex));
            }
        }
    }
}

...全文
235 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
MichaelGLX 03-11
  • 打赏
  • 举报
回复

System.Runtime.InteropServices.Marshal.Copy(
pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);
大概率是数据位没对齐
条码或二维码一般生成图为单通道

__东林 03-06
  • 打赏
  • 举报
回复

请各位大佬指正,非常感谢!!!

111,076

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧