条码 png 打印在 40 毫米 x 15 毫米尺寸标签上的图像在打印时缩小为 20 毫米 x10 毫米且未扫描

Posted

技术标签:

【中文标题】条码 png 打印在 40 毫米 x 15 毫米尺寸标签上的图像在打印时缩小为 20 毫米 x10 毫米且未扫描【英文标题】:Barcode png Image printed on a Label of 40mm x 15mm size is shrunk to 20mm x10mm when printed and not getting scanned 【发布时间】:2020-08-19 02:42:31 【问题描述】:

我遇到了这个问题,我使用 code128 生成条形码并将其保存在 PNG 文件中。 将相同的 PNG 文件提供给具有所需文档属性的打印机作业以在所需尺寸的标签上打印时,尺寸会减小且不会被扫描。

提供的实际打印尺寸 - 40 毫米 x 15 毫米。 标签上印制的尺寸 - 20mm x 10mm

我正在将此属性添加到 PrintRequestAttributeSet - pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM));

但效果并不准确,我试着在那里玩弄x和y参数值,但打印的尺寸仍然在25mm x 10mm之内。

非常感谢任何用于打印所需尺寸条形码的输入。 我在下面给出了完整的代码细节。

(PS:我正在使用“Honeywell PC42t Plus”热敏打印机进行打印,目前我的标签尺寸为 700 毫米 x 280 毫米,我正在等待收到 40 毫米 x 15 毫米尺寸的实际标签。 所以这是为了测试,一旦收到实际标签,我就可以利用整个标签空间打印实际的 40 毫米 x 15 毫米条形码)

public class One_TestMyBarcode 

    private static final String MIME_TYPE = "image/x-png";
    private static final String DELIMTER = "-";
    static String image_name = "NewBarcode_One.png";

    public static void main(String[] args) 

        FileInputStream textStream = null;
        int lastSeqNo = 001;
        String roCode= "ERO";

        AtomicInteger seqNo = new AtomicInteger(lastSeqNo);
        Code128Bean code128 = new Code128Bean();
        code128.setHeight(15f);
        //code128.setBarHeight(40f);
        //code128.setModuleWidth(0.3);
        code128.setModuleWidth(0.2);
        code128.setQuietZone(10);
        code128.doQuietZone(true);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, MIME_TYPE, 300, BufferedImage.TYPE_BYTE_BINARY,
                false, 0);

        StringBuffer codeData = new StringBuffer();
        codeData.append(roCode);
        codeData.append(DELIMTER);

        int currentSeqNo = seqNo.getAndIncrement();
        String seq = String.format("%07d", currentSeqNo);
        codeData.append(seq);
        codeData.append(DELIMTER);
        Calendar current = Calendar.getInstance();
        String year = Integer.toString(current.get(Calendar.YEAR)).substring(2);
        codeData.append(year);

        //logger.debug("barcode dimension is ");
        code128.calcDimensions(codeData.toString());
        code128.generateBarcode(canvas, codeData.toString());

        try 
            canvas.finish();
         catch (IOException e) 
            throw new RuntimeException(e);

        

        FileOutputStream fos = null;
        try 
            //fos = new FileOutputStream("C:\\Users\\Vinayak\\Desktop\\barcode\\" +image_name);
            fos = new FileOutputStream(image_name);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            //textStream = new FileInputStream("C:\\Users\\Vinayak\\Desktop\\barcode\\" +image_name);
            textStream = new FileInputStream(image_name);
         catch (FileNotFoundException e1) 
            e1.printStackTrace();
         catch (IOException e1) 
            e1.printStackTrace();
        

        DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;

        // Position the default print service
        PrintService printService = PrintServiceLookup.lookupDefaultPrintService();

        // Create a print job
        DocPrintJob job = printService.createPrintJob();

        // Set the print properties
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();

        //printed a very small size (20mm x 10mm) and does not scan
        pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM));


        //DOESN'T Scan Either
        //pras.add(OrientationRequested.LANDSCAPE);
        //pras.add(OrientationRequested.PORTRAIT);
        //pras.add(MediaSizeName.ISO_A10);  

        //Doesn't print at all
        //pras.add(new MediaPrintableArea(0, 0, 40, 15, MediaPrintableArea.MM));


        pras.add(new Copies(1));
        DocAttributeSet das = new HashDocAttributeSet();

        // Specify print content
        Doc doc = new SimpleDoc(textStream, flavor, das);

        // Do not display the print dialog, print directly
        try 
               System.err.println("Loop - print");
               job.print(doc, pras); // Make specific print operations for each page

         catch (PrintException pe) 
            pe.printStackTrace();
        

    


【问题讨论】:

用打印机自带的功能创建和打印条码比打印用其他软件创建的条码图像更好吗? PC42t Desktop Printer User Guide - Honeywell Scanning and, How to create a Printer Command Code generator in Windows 根据数据表,打印机理解 ZPL II,它是标签打印机的事实标准打印机语言。在我看来,使用 ZPL II 打印条码比使用通用 Windows 打印机驱动程序打印条码要好,它可以解决所有使条码不可读的烦人驱动程序问题。 @kunif,感谢您的评论。我理解您的观点,但我目前的项目要求是根据用户登录详细信息和序列号从 Web 应用程序实时生成条形码,并将此字符串编码为 40mm x 15mm 大小的条形码标签。 @ErichKitzmueller 谢谢。我目前正在使用霍尼韦尔 PC42t Plus 热敏打印机。根据共享的 Java 代码,我可以直接调用打印机并打印条形码,唯一的问题是打印的条形码尺寸不是预期的尺寸。 pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM));我希望标签打印 40 毫米 x 15 毫米的条码,但实际上它在打印时会生成 20 毫米 x 10 毫米大小的条码。所以我需要在那里得到实际尺寸。 (PS:我目前的标签尺寸是 70mm x 28mm,我在最初的帖子中错误地提到它为 700mm x 280mm) 如果是这样,作为条形码创建前提的分辨率和计算值是不是有错误?打印机的分辨率为 203dpi。也许您需要为它创建一个位图并逐点打印? 【参考方案1】:

您可以使用打印机语言而不是像使用通用打印机一样使用条形码打印机,从而使您的程序更短、更快,并确保它始终打印清晰的条形码。

import javax.print.*;

public class PrintUsingZPL 
  public static void main(String[] args) 
    StringBuilder codeData = new StringBuilder();
    codeData.append("***"); // example

    String printCommand = "^XA^LH0,0^FO50,50^BCN,100,Y,N,N^FD"+
                          codeData.toString()+
                          "^FS^XZ";
    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    try 
      DocPrintJob job = printService.createPrintJob();
      Doc doc = new SimpleDoc(printCommand.getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
      job.print(doc, null);
    
    catch(PrintException e)  /* error handling goes here */ 
  

【讨论】:

感谢@ErichKitzmueller 提供详细的代码和信息。我使用您的程序验证了标签打印的原样,打印机刚刚推出了一个空标签。我已将打印机设置保留为 ZSim、ESim 和 DPL 的默认值。 (我正在使用 Honeywell PrintSet 5 工具来配置打印机)。我错过了什么吗? @VinayakSatapute 我在示例程序中插入了一个 ^LH 命令,该命令将标签设置为 home - 也许这会有所帮助。如果不是,请为 ^FO(字段来源)命令尝试一些其他值 - 有时其他设置的组合会将条形码完全放在标签之外。确保您的打印机设置为使用 ZSim 作为打印机语言。您也可以尝试使用 DPL 而不是 ZPL II;我认为它更适合您的打印机。【参考方案2】:

感谢@Erich。我已经使用了您给定的代码并更新了 ZPL 和 DP 语言的 printCommand。您更新的代码 (^LH) 能够打印条形码,但没有被扫描(不确定,我尝试了一些变体但没有帮助),所以我在那里尝试了 DPL 命令,如代码所示,它能够打印条形码并成功扫描。非常感谢您的帮助和指导。


package BARCODE;

import javax.print.*;
import javax.print.PrintService;

public class PrintUsingZPL1 
  public static void main(String[] args) 
    StringBuilder codeData = new StringBuilder();
    //codeData.append("***"); // example
    codeData.append("CRO-0000100-20"); // example
    String printData = codeData.toString();
    System.out.println("Data for Barcode " +printData);

    /*String printCommand = "^XA^LH0,0^FO50,50^BCN,100,Y,N,N^FD"+
                          codeData.toString()+
                          "^FS^XZ";*/

   /* String printCommand = "PP65,107:AN7\r\n" + 
            "BARSET \"CODE128B\",2,1,1,71\r\n" + 
            "PB \"CRO-0000001-20\"\r\n" + 
            "PP79,37:NASC 8\r\n" + 
            "FT \"CG Triumvirate Condensed Bold\",8,0,98\r\n" + 
            "PT \"CRO-0000001-20\"\r\n" + 
            "LAYOUT RUN \"\"\r\n" + 
            "PF"; */
  String printCommand = "PP35,90:AN7\r\n" + 
    "BARSET \"CODE39A\",3,1,1,67\r\n" + 
    "PB " +codeData.toString()+ "\r\n" + 
    "PP65,23:NASC 9\r\n" + 
    "FT \"Andale Mono Bold\",8,0\r\n" + 
    "PT " +codeData.toString()+ "\r\n" + 
    "LAYOUT RUN \"\"\r\n" + 
    "PF";

    /*String printCommand = "PP65,107:AN7\r\n" + 
            "BARSET \"CODE128B\",2,1,1,71\r\n" + 
            "PB "+printData+"\r\n" + 
            "PP79,37:NASC 8\r\n" + 
            "FT \"CG Triumvirate Condensed Bold\",8,0,98\r\n" + 
            "PT "+printData+"\r\n" + 
            "LAYOUT RUN \"\"\r\n" + 
            "PF";*/

    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    try 
      DocPrintJob job = printService.createPrintJob();
      Doc doc = new SimpleDoc(printCommand.getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
      job.print(doc, null);
    
    catch(PrintException e)  /* error handling goes here */ 
  


【讨论】:

Vinayak - 不要忘记接受您的回答,以便未来的访问者也可以放心地使用该解决方案。查看meta.stackexchange.com/questions/5234/… 了解如何操作。 很抱歉,我无法回复您的消息。不是我错过了你的信息……我收到了信息,只是忙于某件事,后来它从我的脑海中溜走了。 谢谢@Arvind,我已经更新了 printCommand 的答案。

以上是关于条码 png 打印在 40 毫米 x 15 毫米尺寸标签上的图像在打印时缩小为 20 毫米 x10 毫米且未扫描的主要内容,如果未能解决你的问题,请参考以下文章

mfc怎样把逻辑坐标换算成物理坐标

空开大小与导线大小关系

PCL:以毫米为单位计算一个点的 xyz

如何将图像尺寸(宽度/高度)转换为毫米?

24GHz和77GHz毫米波雷达技术细节

如何使用相机矩阵在图像中以毫米为单位查找点的位置?