精华内容
下载资源
问答
  • Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印 一、前言 Android 打印解决文字显示?...如下图,打印是一栏地址,原来第三个字呢打印出来是 ? 号 ,这张图是用以下转换方法修复

    Android 打印之将文字转换成 Bitmap 图片,再转换成Bytes 数组 进行打印

    一、前言

    Android 打印解决文字显示?问好 乱码

    最近在处理打印的时候,打印机有些繁体的字无法打印出来,或者其它韩文打印出来显示 ? 问题

    解决思路:

    将需要打印的 String 文本内容,先转换成 Bitmap 位图 , 然后将图片转换成打印机能打印的byte[]类型

    不同印机 最终丢给印机打印的方法不同。

    如下图,打印的是一栏地址,原来第三个字呢打印出来是 ? 号的 ,这张图是用以下的转换方法修复后的。

    使用印机都是 EPSON,其它也类似。

    左边的是 网络打印 (通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区)

    右边的是 USB 连接 EPSON 打印 (通过EPSON SDK的方法,addImage() ) 打印出来的很OK

    其实还有一个问题就是,通过网络传递的Esc 指令打印之后,打印文字可能打印像素有点不全的问题 ,我感觉是 下面的 genBitmapCode 方法 转换出来的时候,像素精度还是什么问题 ,如果有好的解决方式 请给我留言 谢谢。(文末已找到完美解决方式)

    后面发现,如果打印的文字很大的话,或者给文字 设置字体是加粗的话 就 不会打印出来是缺像素的,不过其实这样也不太好。总之目前就是如果是有SDK的,就优先使用专门的打印 Bitmap 的方法, 而网络打印只能发 Esc 指令发送Bytes。

        String familyName ="宋体";
        Typeface font = Typeface.create(familyName,Typeface.BOLD);
        textPaint.setTypeface(font);
    

    在这里插入图片描述

    下面提供了 ,创建Bitmap 图片, 创建 QRCode 二维码图片 ,转换成 Bytes 数组 进行打印

    二、将文字转换成Bitmap

        /**
         * 根据文字创建一个 bitmap  , 打印的位图需要 黑字 白底
         *
         * @param text
         * @param height
         * @param width
         * @return
         */
        public Bitmap getNewBitMap(String text, int height, int width) {
            Bitmap newBitmap = createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(newBitmap);
            canvas.drawColor(Color.WHITE);
    
            canvas.drawBitmap(newBitmap, 0, 0, null);
            TextPaint textPaint = new TextPaint();
           //       String familyName ="宋体";
          //  Typeface font = Typeface.create(familyName,Typeface.BOLD);
           // textPaint.setTypeface(font);
            textPaint.setAntiAlias(true);
            textPaint.setTextSize(height * 2 / 3);
    //        textPaint.setColor(Color.rgb(0, 0, 0));
            textPaint.setColor(Color.BLACK);
            //     "在Android开发中,Canvas.drawText不会换行,即使一个很长的字符串也只会显示一行,超出部分会隐藏在屏幕之外.StaticLayout是android中处理文字的一个工具类,StaticLayout 处理了文字换行的问题";
            StaticLayout sl = new StaticLayout(text, textPaint, newBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            textPaint.setStyle(Paint.Style.FILL);
            canvas.translate(0, height / 10);
            sl.draw(canvas);
            return newBitmap;
        }
    
    
        /**
         * 生成二维码bitmap 要转换的地址或字符串,可以是中文
         *
         * @param url
         * @param width
         * @param height
         * @return
         */
        public Bitmap createQRImage(String url, final int width, final int height) {
            try {
                // 判断URL合法性
                if (url == null || "".equals(url) || url.length() < 1) {
                    return null;
                }
                Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
                // 图像数据转换,使用了矩阵转换
                BitMatrix bitMatrix = new QRCodeWriter().encode(url,
                        BarcodeFormat.QR_CODE, width, height, hints);
                int[] pixels = new int[width * height];
                // 下面这里按照二维码的算法,逐个生成二维码的图片,
                // 两个for循环是图片横列扫描的结果
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        if (bitMatrix.get(x, y)) {
                            pixels[y * width + x] = 0xff000000;
                        } else {
                            pixels[y * width + x] = 0xffffffff;
                        }
                    }
                }
                // 生成二维码图片的格式,使用ARGB_8888
                Bitmap bitmap = createBitmap(width, height,
                        Bitmap.Config.ARGB_8888);
                bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
                return bitmap;
            } catch (WriterException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    
    
    

    三、把图片转换成POS机能打印的byte[]类型

      /**
         * 将图片转换成POS机能打印的byte[]类型
         *
         * @param bm
         * @param doubleWidth
         * @param doubleHeight
         * @return
         */
        private static byte[] genBitmapCode(Bitmap bm, boolean doubleWidth, boolean doubleHeight) {
            int w = bm.getWidth();
            int h = bm.getHeight();
    //        if(w > MAX_BIT_WIDTH)
    //            w = MAX_BIT_WIDTH;
            int bitw = ((w + 7) / 8) * 8;
            int bith = h;
            int pitch = bitw / 8;
            byte[] cmd = {0x1D, 0x76, 0x30, 0x00, (byte) (pitch & 0xff), (byte) ((pitch >> 8) & 0xff), (byte) (bith & 0xff), (byte) ((bith >> 8) & 0xff)};
            byte[] bits = new byte[bith * pitch];
            // 倍宽
            if (doubleWidth) {
                cmd[3] |= 0x01;
            }
            // 倍高
            if (doubleHeight) {
                cmd[3] |= 0x02;
            }
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    int color = bm.getPixel(x, y);
                    if ((color & 0xFF) < 128) {
                        bits[y * pitch + x / 8] |= (0x80 >> (x % 8));
                    }
                }
            }
    
            ByteBuffer bb = ByteBuffer.allocate(cmd.length + bits.length);
            bb.put(cmd);
            bb.put(bits);
    
            return bb.array();
        }
    

    四、调用打印文本方式

          //生成的bitmap 显示 固定是一行 ,如果要生成多行,需要自行通过文本控制Bitmap的宽高
                    Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);
    
                    byte[] bytes = genBitmapCode(newBitMap, true, true);
                     
    							//此方式是网络打印 通过 OutputStream 流的方式 将 byte[] 写入 到缓冲区
                    socketOut.write(bytes);
    							
    
    

    五、EPSON 爱普生 中打印图片的方式

    	       //创建单行文字 
     					Bitmap newBitMap = getNewBitMap(IMAGE, 40, 600);
    
                //打印图片 方式 1  打印出来很漂亮
                mPrinter.addImage(newBitMap, 0, 0,
                        newBitMap.getWidth(),
                        newBitMap.getHeight(),
                        Printer.COLOR_1,
                        Printer.MODE_MONO,
                        Printer.HALFTONE_DITHER,
                        Printer.PARAM_DEFAULT,
                        Printer.COMPRESS_AUTO);
    		
    		// 方式2 打印出来 有少像素没打全
    		  Bitmap newBitMap = getNewBitMap(IMAGE, 20, 300);
    
                byte[] bytes = genBitmapCode(newBitMap, true, true);
                     
    			mPrinter.addCommand(bytes)
    

    六、调用打印二维码图片

    
    		          Bitmap qrImage = createQRImage("qr123456", 170, 170);
    
                    byte[] bytes = genBitmapCode(qrImage, true, true);
    
                    socketOut.write(bytes);
    

    以上代码只是作为一个参考思路, 主要是 将 String 转换 为 Bitmap ,再丢给打印机 进行打印。

    不同印机应优选考虑不同的调用方式,如果是 USB 连接 EPSON 的话 其实也支持 Esc 指令 进行命令打印的。

    网络打印的话,只能传递 Esc 指令集 通过流的方式传输进行打印了。


    X、 解决图片像素打印不全问题

    经过排查,使用了另外一种创建 Bitmap 的方式,可正常进行完美打印不会像素失真, 另外也可以使用另外一种 将 Bitmap 图片转化为打印机可以打印的字节流的方法

    
    	 /**
         * 将文字 生成 文字图片 生成显示编码的Bitmap,目前这个方法是可用的 ,  打印的位图需要 黑字 白底
         * @param contents
         * @param context
         */
        public static Bitmap creatCodeBitmap(String contents ,Context context) {
            float scale=context.getResources().getDisplayMetrics().scaledDensity;
    
            TextView tv = new TextView(context);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            tv.setLayoutParams(layoutParams);
            tv.setText(contents);
            tv.setTextSize(scale*12);
            tv.setGravity(Gravity.CENTER_HORIZONTAL);
            tv.setDrawingCacheEnabled(true);
            tv.setTextColor(Color.BLACK);
            tv.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
    
            tv.setBackgroundColor(Color.WHITE);
    
            tv.buildDrawingCache();
            Bitmap bitmapCode = tv.getDrawingCache();
            return bitmapCode;
        }
    
    
      /**
         * 把一张Bitmap图片转化为打印机可以打印的字节流
         *
         * @param bmp
         * @return
         */
        public static byte[] draw2PxPoint(Bitmap bmp) {
            //用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法
            //整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,
            //但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,
            //所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。
            int size = bmp.getWidth() * bmp.getHeight() / 8 + 1000;
            byte[] data = new byte[size];
            int k = 0;
            //设置行距为0的指令
            data[k++] = 0x1B;
            data[k++] = 0x33;
            data[k++] = 0x00;
            // 逐行打印
            for (int j = 0; j < bmp.getHeight() / 24f; j++) {
                //打印图片的指令
                data[k++] = 0x1B;
                data[k++] = 0x2A;
                data[k++] = 33;
                data[k++] = (byte) (bmp.getWidth() % 256); //nL
                data[k++] = (byte) (bmp.getWidth() / 256); //nH
                //对于每一行,逐列打印
                for (int i = 0; i < bmp.getWidth(); i++) {
                    //每一列24个像素点,分为3个字节存储
                    for (int m = 0; m < 3; m++) {
                        //每个字节表示8个像素点,0表示白色,1表示黑色
                        for (int n = 0; n < 8; n++) {
                            byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);
                            data[k] += data[k] + b;
                        }
                        k++;
                    }
                }
                data[k++] = 10;//换行
            }
            return data;
        }
    
    
    

    使用方式

         //生成的bitmap 显示 固定是一行
    
                    Bitmap bitmap = creatCodeBitmap(IMAGE, App.getInstance());
                    byte[] bytes = draw2PxPoint(bitmap);
                    
                    socketOut.write(bytes);
    

    借鉴

    android 字符串 转换成Bitmap 设置文本的字体: 宋体,隶书啥的,获取字体的 行高, 文字生成图片

    展开全文
  • CXF调用.NETWebService,在WebService中返回一个string[]数组,而在WSDL中描述为ArrayOfString,请问我该如果转化...打印出来的是一个ArrayOfString类型。我该怎样取得里面数据呢?这样调对不对?还有别办法吗?
  • 输入一个整数数组,把数组例多有数字拼接起来排成一个数,打印出来能拼接出来所有数字中最小一个。 示例: 输入:{3,32,321} 输出:321323 分析: 思路1: 该题目主要对排列组合考察。如果熟悉对STL...

    索引请参考:系列目录
    题目:

    • 输入一个整数数组,把数组例多有数字拼接起来排成一个数,打印出来能拼接出来的所有数字中最小的一个。
    • 示例:
    • 输入:{3,32,321}
    • 输出:321323

    分析:
    思路1:

    • 该题目主要是对排列组合的考察。如果熟悉对STL熟悉的小伙伴,应该是一道很简单的题目

    思路2:

    • 对输入数组转化成string类型,然后对其进行升序排序。得到的便是最小是最小的拼接数

    方法1:

    std::string ret(number.size(), '9');
    	std::sort(number.begin(), number.end());
    	do
    	{
    		std::string temp;
    		for (auto elem : number)
    			temp += std::to_string(elem);
    		ret = std::min(temp, ret);
    		std::cout << temp << std::endl;
    
    	} while (std::next_permutation(number.begin(),number.end()));
    	
    	return ret;
    

    牛客运行结果:
    在这里插入图片描述
    方法2:

    std::vector<std::string> str;
    	for (auto elem : number)
    		str.push_back(std::to_string(elem));
    	auto cmp = [](std::string a,std::string b) {
    	
    		return a + b < b + a;
    
    	};
    	std::sort(str.begin(), str.end(), cmp);
    	std::string ret;
    	for (auto elem : str)
    		ret += elem;
    	return ret;
    

    牛客运行结果:
    在这里插入图片描述
    评注:可以看出两种方法各有利弊。在注重时间效率的情况下,应该更加偏向方法1.在注重空间效率的情况下,应该更加偏向方法2。导致方法2时间效率不高的原因是:用标准模板库中的sort算法。该算法在正常情况下用的快排算法,最差情况下,用的是堆排算法。这样排序算法时间复杂度会从线性变为nlogn。

    展开全文
  • 后面程序TestIfError.java我们想打印的是中年人,但打印出来的结果青年人。 • 对于任何if else 语句,表面上看起来else后没有任何条件,或者else if后只有一个条件,但这不是真相:因为 else含义...
  • 结论: 数组,无论是否声明为...将数组 按ObjectOutput存入文件,使用ObjectInputStream读取打印出来。结果我发现无论基本类型还是引用类型,无论 是否将数组修饰为transient,都可以序列化和反序列化。贴一...

    结论:  数组,无论是否声明为transient,都是可以序列化、反序列化的。

    测试情况如下:

    1.两种类型的数组:int 、String;

    2 声明为transient  或者不做任何修饰;.

    3.将数组 按ObjectOutput存入文件,使用ObjectInputStream读取打印出来。

    结果我发现无论是基本类型还是引用类型,无论 是否将数组修饰为transient,都是可以序列化和反序列化的。

    贴一段代码如下:

    File file = new File("test.txt");

    FileOutputStream fout = new FileOutputStream(file);

    ObjectOutputStream objOut = new ObjectOutputStream(fout);

    objOut.writeObject(arrs);

    objOut.close();

    FileInputStream fin = new FileInputStream(file);

    ObjectInputStream objectInputStream = new ObjectInputStream(fin);

    int[] arrs = (int[]) objectInputStream.readObject();

    for (int str : arrs) {

    System.out.println(str);

    }

    这个问题是我在看ArrayList的源码时, 发现的,ArrayList中定义数组如下:

    private transient Object[] elementData;;

    将ArrayList序列化和反序列化都是可以 读取 其中的值的,so最后测试了下数组,发现了这个问题.

    不知道 结论对不对, 求  修正我的 问题。

    我查看了这篇文章:

    但是他好像仅解释了为什么使用修饰  ArrayList中的数组,却没有说清楚(不知道是否我 理解 有问题)为什么  ArrayList 序列化、反序列化 都是可以 。

    展开全文
  • 数组排成最小数

    2016-09-16 12:42:12
    题目:输入一个正数数组,把数组中所有数字拼接起来排成一个数,打印能排列出来的最小那一个例如输入{3,32,321} 输出应该 321323 这个题目直观做法先求出所有可能排列,然后找到最小那个。但是...

    题目:输入一个正数数组,把数组中所有的数字拼接起来排成一个数,打印能排列出来的数的最小的那一个例如输入{3,32,321} 输出的应该是 321323

    这个题目的直观做法是先求出所有可能的排列,然后找到最小的那个。但是n个数字的排列有n!个,时间复杂度太高。

    同时应该注意,如果直接将输出类型定义为int类型的话,如果数组中的值比较大,加合完之后的值可能会超出int类型,因此最好用string 类型存储最终结果。

    通过这道题我也复习了一下 c++ 的sort 和qsort 的用法(虽然后面代码用的sort )以及对应的cmp 函数的写法。

    下面是我实现的代码

    class Solution {
        
    public:
       static bool cmp(string a,string b){
            string t1 = a+b;
            string t2 = b+a;
            return t1 < t2;
        }
        string PrintMinNumber(vector<int> numbers){
            vector<string> numstr;
            for(int i =0;i<numbers.size();i++){
                char temp[10];
                sprintf(temp,"%d",numbers[i]);
                numstr.push_back(temp);
            }
            sort(numstr.begin(),numstr.end(),cmp);
            string result = "";
            for(int i=0;i<numstr.size();i++) result+=numstr[i];
            return result;
            
        }
    };


    展开全文
  • 然而我们String类里重写了toString(),它返回的是String自己,String是什么呢,String其实就是字符数组(),它内部封装了一个字符数组,所以打印字符串就是打印字符数组,而不是地址 关于Java中String内存地址...
  • 1.for in 在遍历数组的时候,遍历出来的值默认是string类型。 var a=[1,2,3]; for(i in a){  alert(typeof(i)); //尽管是一个数字数组,但还是会打印输出string } 2.for in 遍历对象的时候不一定按章顺序遍历 var...
  • 两个数组是否相同,我们想到最后打印出来的结果应该true或者false 所以我们要用到Boolean类型去调用与接受 我们接下来,来看一下代码 public class Shuzuxiangtong { public static void main(String[] args) { //...
  • 结论: 数组,无论是否声明为transient,都可以序列化、反...3.将数组 按ObjectOutput存入文件,使用ObjectInputStream读取打印出来。   结果我发现无论基本类型还是引用类型,无论 是否将数组修饰为transient,
  • 方法中参数一个数组Object,我只想想使用foreach打印出来,但是会报错: ArrayGrowTest.java:43: foreach 不适用于表达式类型 for (Object o : object ) { ^ 1 错误 看大家有什么解决方法吗? PS:...
  • 我想要做的是编写一个应用程序,它接收未知数量名称,然后在新页面上打印出来。这应该一个保龄球得分应用程序,但现在我只想得到一个名称列表。这个想法为每个名字进入一个玩家对象,然后存储在玩家数组列表中...
  • 曾经有一段时间我一直认为new String()和toString一样...这两个结果打印出来你会发现还是不一样 Java对象都继承于Object,Object中提供了toString方法,用于简单返回该类类签名。在Java中,数组也可以看作一种
  • 解题思路:用一个int类型的数组依次存放每位数据,第一次取模10,得到的是个位数,除以10之后再取模得到十位数,正好逆序,可以直接输出。另外用一个temp变量存储该数据长度,当n等于0时候,说明所有数据都...
  • 上面这段代码,我们首先创建了一个Person类,包含了Name和Age两个属性,毋庸置疑,Person类是引 用类型,Name也是,因为它是string类型的(但string是很特殊引用类型,后面将专门有一篇文章来讨论),但Age则是值...
  • 一个MD5工具类 ``` package org.fkjava.util; import java.math.BigInteger;...但是我用计算器算了一下,“e1”16进制,换成10进制应该225,为什么我打印出来的是101呢,代码哪里有问题吗?
  • 数据类型的分类 基本数据类型 数字(number) 字符串(string) ...字符串,用引号引起来数据 在控制台打印出来的颜色黑色 var str = '123'; 布尔:只有两个值 : true || false var flag = true; 4
  • php数据类型

    2017-12-01 22:34:00
    记得上篇中最后用var_dump函数打印出来的数据前面显示的是数据类型,这篇就对php数据类型做个简单说明。 PHP数据类型有哪些? String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), ...
  • java基础中Arrays.toString()方法

    千次阅读 2020-12-30 11:23:57
    在学完数组以后,如果想要把数组中的内容打印出来,直接调用toString()方法只会打印出数组的地址,因此需要使用Arrays的toString()方法。 //代码截图如下: 通过源码我们可以看出Arrays的toString()方法一个重载的...
  • SHA,MD5,HmacMD5三种加密方式代码

    万次阅读 2012-01-29 11:52:35
    --初学者使用 网上关于HmacMD5加密方式太少,仅有文章 初学者来说也晦涩难懂...备注:由于数组未重写toString方法,所以不要将方法返回的数组类型直接打印出来 public static void main(String[] args) throws Ex
  • // 打印出3,因为该是数组有3个元素 // 用一个语句定义一个数组并赋值 $myphonebook = array ( "sbabu" => "5348", "keith" => "4829", "carole" => "4533" ); // 噢,忘了教长吧,让我们添加一个元素 $myphonebook...
  • 引用数据类型名称所代表的是地址,地址为二进制数字,当我们试图打印内存地址时,它会以16进制方式表现出来。所以地址实质还是整型数字,属于基本数据类型,所以他和基本数据类型共同存放在栈中。(栈也只存放...
  • Spark如何遍历Rdd中元素

    千次阅读 2020-07-02 14:03:18
    RDD[String]类型又不能直接打印出来结果,或者说有遇到需要将rdd中结果数据取出作为变量继续计算情况。 1) 使用 collect 函数 从collect函数解释来看,知道collect返回类型是一个数组,可以通过下标或 ....
  • 1.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 42 声明问题 43 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 43 *1.26 main的正确定义...
  • 1.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 42 声明问题 43 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 43 *1.26 main的正确定义...
  • 你必须知道495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    6.21 当数组函数的参数时,为什么sizeof不能正确报告数组的大小? 6.22 如何在一个文件中判断声明为extern的数组的大小(例如,数组定义和大小在另一个文件中)?sizeof操作符似乎不行。 6.23 sizeof返回的大小...
  • 6.21 当数组函数的参数时,为什么sizeof不能正确报告数组的大小?  6.22 如何在一个文件中判断声明为extern的数组的大小(例如,数组定义和大小在另一个文件中)?sizeof操作符似乎不行。  6.23 sizeof返回的...
  • [你必须知道的495个C语言问题] 第1章 声明和初始化 基本类型 1.1 我该如何决定使用哪种整数类型?... 数组的指针 6.12 既然数组引用会退化为指针,如果array数组,那么array和&array;又有什么区别...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 121
精华内容 48
关键字:

数组的类型打印出来是string