我们可以将图像转换为字节数组,以便发送到ESC / POS打印机
我在这里使用代码:https://stackoverflow.com/a/14099717/1853275
它就像魅力一样。
简单问题:是否可以将此字节数组转换回原始图像? 如果有,请告诉我如何...
更大的图片:
我创建了一个TCP / IP监听器,它充当POS打印机
它从POS应用程序接收数据,然后转发到真正的打印机
介于两者之间,我必须在收据上打印产品,并根据产品打印一些额外的东西
所以,我需要将图形数据转换为图像(然后是OCR)以便在收到时读取产品。
这里有一张获得的ESC / POS收据:
pastebin.com/vUDHjGuj
(我们可以将它转换为字节数组,然后发送到打印机。它会打印收据。)
我知道捕获数据的结构。我们可以删除ESC / POS命令并将数组拆分为0x0A LF。我只需要一种方法将图形字节数组转换为图像并将切片放在一起以创建收据图像 发送到打印机的图形模式是:24位双密度(0x1B 0x2A 0x21)
请帮忙......
非常感谢
public static Bitmap FromByteArray(byte[] ByteArray, Size Size)
{
Bitmap bmp = new Bitmap(Size.Width, Size.Height, PixelFormat.Format24bppRgb);
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, Size.Width, Size.Height),ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpdata.Scan0;
System.Runtime.InteropServices.Marshal.Copy(ByteArray, 0, ptr, ByteArray.Length);
bmp.UnlockBits(bmpdata);
return bmp;
}
答案 0 :(得分:3)
您正在使用打印机的页面描述语言,因此首先要注意这不是入门级任务。
在您的代码中,没有特定的“修复”。它似乎是基于一些不基于这种数据格式现实的假设。
因此,如果您想要使用C#代码,如评论中所述,您需要正确地反转您链接的C#示例中的过程。您可以通过一个好的调试器,ESC *
ESC *
的副本以及一些要转换的小样本文件来告知这项工作。
完全可以解析ESC / POS以恢复原始图像。我维护一个开源项目来执行此操作,它将处理您的示例文件(Epson documentation,github)。用于解析cat esc_pos_graphics_printing_data.txt | tr -d '\r' | tr -d '\n' | \
python3 -c "import sys, binascii; sys.stdout.buffer.write(binascii.unhexlify(input().strip()))" > \
esc_pos_graphics_printing_data.bin
related blog post的代码。它不是C#,但它有效。
我必须将您的示例文件转换回二进制文件才能使用它:
escpos-tools
然后,为了从收据中提取图片并加入图片,我使用git
(composer
,php
,ImageMagick
)加git clone https://github.com/receipt-print-hq/escpos-tools.git
cd escpos-tools
composer install
php escimages.php --file ../esc_pos_graphics_printing_data.bin
convert esc_pos_graphics_printing_data-*.png -append output.png
:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;
public class Drugfragment extends Fragment {
View view;
public Drugfragment() {
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.drugfragment, container, false);
final Spinner spin1 = view.findViewById(R.id.spinnerFrequency);
final Spinner spin2 = view.findViewById(R.id.SpinnerTime);
final Spinner spin3 = view.findViewById(R.id.SpinnerQty);
Button save = view.findViewById(R.id.btnSave);
ArrayAdapter<CharSequence> arrayAdapter = ArrayAdapter.createFromResource(getContext(), R.array.Qty, android.R.layout.simple_spinner_dropdown_item);
ArrayAdapter<CharSequence> arrayAdapter2 = ArrayAdapter.createFromResource(getContext(), R.array.time, android.R.layout.simple_spinner_item);
ArrayAdapter<CharSequence> arrayAdapter3 = ArrayAdapter.createFromResource(getContext(), R.array.frequency, android.R.layout.simple_spinner_item);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
arrayAdapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
arrayAdapter3.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin1.setAdapter(arrayAdapter);
spin2.setAdapter(arrayAdapter2);
spin3.setAdapter(arrayAdapter3);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = spin1.getSelectedItem().toString();
String text2 = spin2.getSelectedItem().toString();
String text3 = spin3.getSelectedItem().toString();
Toast.makeText(getContext(), "text1: " + text + "\ntext2: " + text2 + "\ntext3: " + text3, Toast.LENGTH_SHORT).show();
}
});
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
收据是:
is located in SelectBitImageMode.php
祝你好运!