android canvas zxing 二维码位置

iefus 2017-05-30 11:32:39
50mm*15mm 的长方形纸上,需要打印文字和二维码。文字靠左边,二维码靠右边。
为什么生成的图片,始终是一个正方形的二维码。我调整destRect right,bottom 的值,图形位置也不边


Bitmap bmp = Bitmap.createBitmap(1600, 600, Config.ARGB_4444);
Rect srcRect = new Rect(0, 0, 160, 160);
Rect destRect = new Rect(0, 0, 1200, 400);

Canvas can = new Canvas(bmp);
Paint m_pat = new Paint();
m_pat.setColor(Color.WHITE);
m_pat.setAntiAlias(true);
m_pat.setTextAlign(Align.CENTER);
//can.drawBitmap(bitmap, (2800 - bitmap.getWidth()) / 2, 0, m_pat);
can.drawRect(new Rect(0, 0, 1200, 400), m_pat);
//bitmap 为生成的二维码,160*160
can.drawBitmap(bitmap, srcRect, destRect, m_pat);
...全文
296 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
iefus 2017-11-14
  • 打赏
  • 举报
回复
最后先生成一个长方形画布,然后再添加二维码解决了。 来人接分

package com.jcap.mms.util;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 二维码生成工具类
 */
public class QRCodeUtil {
	
	private static int QRCODE_SIZE = 160;
	
	/**
	 * 生成二维码Bitmap
	 *
	 * @param content
	 *            内容
	 * @param widthPix
	 *            图片宽度
	 * @param heightPix
	 *            图片高度
	 * @param logoBm
	 *            二维码中心的Logo图标(可以为null)
	 * @param filePath
	 *            用于存储二维码图片的文件路径
	 * @return 生成二维码及保存文件是否成功
	 */
	public static String createQRImage(Map<String, Object> paramMap,int width, int height, int space, Bitmap logoBm, String filePath) {
		
		HashMap<String,String> hashMapBarcode = new HashMap<String,String>();
		
		try {			
			
			int from = (int)paramMap.get("from");
			int to = (int)paramMap.get("to");
			
			
			// 配置参数
			// HashMap<encodehinttype, object=""> hints = new HashMap<>();
			HashMap<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();

			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			// 容错级别
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

			// 设置空白边距的宽度
			// hints.put(EncodeHintType.MARGIN, 2); //default is 4
			
			ArrayList<String> strList = (ArrayList<String>)paramMap.get("stringList");
			
			for(int i= from;i<=to;i++ ){
				
				ArrayList<String> listTmp = new ArrayList<String>();
				listTmp.addAll(strList);
				String barcode = paramMap.get("barcode").toString();
				
				if(i>0){
					barcode += "-"+String.format("%03d", i);
				}
				listTmp.add(barcode);
				
				//int widthBarcode = height*8;
				//int heightBarcode = height*8;
				
				// 图像数据转换,使用了矩阵转换
				BitMatrix bitMatrix = new QRCodeWriter().encode(barcode, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
				int w = bitMatrix.getWidth();
				int h = bitMatrix.getHeight();
				int[] pixels = new int[w * h];
				// 下面这里按照二维码的算法,逐个生成二维码的图片,
				// 两个for循环是图片横列扫描的结果
				for (int x = 0; x < w; x++) {
					for (int y = 0; y < h; y++) {
						if (bitMatrix.get(x, y)) {
							pixels[y * w + x] = 0xff000000;
						} else {
							pixels[y * w + x] = 0xffffffff;
						}
					}
				}

				// 生成二维码图片的格式,使用ARGB_8888
				Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
				bitmap.setPixels(pixels, 0, w, 0, 0, w, h);

				if (logoBm != null) {
					bitmap = addLogo(bitmap, logoBm);
				}

				bitmap = drawText(bitmap,listTmp,width,height,space);
				//bitmap.recycle();

				barcode += ".jpg";
				// 必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath+barcode));
				hashMapBarcode.put(barcode,filePath+barcode);
			}			
			
		} catch (WriterException | IOException e) {
			e.printStackTrace();
		}

		Gson gson = new Gson();
		return gson.toJson(hashMapBarcode);
	}

	private static Bitmap drawText(Bitmap bitmap,ArrayList<String> strList, int width,int height, int space) {
		
		//Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth()*5, (int)(bitmap.getHeight()*1.3), Config.ARGB_8888);
		Bitmap bmp = Bitmap.createBitmap(384, (height+space)*8, Config.ARGB_8888);
		
		Canvas can = new Canvas(bmp);
		Paint m_pat = new Paint();
		m_pat.setColor(Color.WHITE);
		m_pat.setAntiAlias(true);
		m_pat.setTextAlign(Align.CENTER);
		
		//can.drawRect(new Rect(0, 0, 1600, 600), m_pat);
		//can.drawBitmap(bitmap, srcRect, destRect, m_pat);
		//can.drawRect(new Rect(0, 0, bitmap.getWidth()*5, (int)(bitmap.getHeight()*1.3)), m_pat);
		can.drawRect(new Rect(0, 0, 384, (height+space)*8), m_pat);
		//can.drawBitmap(bitmap, bmp.getWidth()-(float)(bitmap.getWidth()), (bmp.getHeight()-bitmap.getHeight())/2, m_pat);
		can.drawBitmap(bitmap, bmp.getWidth()-(float)(bitmap.getWidth()), -20, m_pat);
		
		int size = 24;
		int top = 0;
		m_pat.setAntiAlias(true);
		m_pat.setTextAlign(Paint.Align.LEFT);
		
		for(int i=0;i<strList.size();i++){
			PrintOneString(can, m_pat, strList.get(i).toString(), size, 0, top, 40, 0);
			top += 26;
		}
		
		return bmp;
	}

	private static void PrintOneString(Canvas can, Paint pat, String str, int textSize, int left, int top,int viewHeight, int viewWidth) {
		pat.setTextSize(textSize);
		FontMetrics fm = pat.getFontMetrics();

		// 文本的宽度
		float textWidth = pat.measureText(str);
		// textWidth = textWidth > (viewWidth * 1.0f) ? (viewWidth * 1.0f) :
		// textWidth;
		float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;

		float textCenterX = (float) viewWidth / 2;
		float textBaselineY = textCenterVerticalBaselineY;

		if (str.length() > 0) {
			pat.setColor(Color.BLACK);
			can.drawText(str, textCenterX + left, textBaselineY + top, pat);
		}
	}

	/**
	 * 在二维码中间添加Logo图案
	 */
	private static Bitmap addLogo(Bitmap src, Bitmap logo) {
		if (src == null) {
			return null;
		}

		if (logo == null) {
			return src;
		}

		// 获取图片的宽高
		int srcWidth = src.getWidth();
		int srcHeight = src.getHeight();
		int logoWidth = logo.getWidth();
		int logoHeight = logo.getHeight();

		if (srcWidth == 0 || srcHeight == 0) {
			return null;
		}

		if (logoWidth == 0 || logoHeight == 0) {
			return src;
		}

		// logo大小为二维码整体大小的1/5
		float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
		Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
		try {
			Canvas canvas = new Canvas(bitmap);
			canvas.drawBitmap(src, 0, 0, null);
			canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
			canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);

			canvas.save(Canvas.ALL_SAVE_FLAG);
			canvas.restore();
		} catch (Exception e) {
			bitmap = null;
			e.getStackTrace();
		}

		return bitmap;
	}

}
djegg2008 2017-11-14
  • 打赏
  • 举报
回复
谢谢提供,,
Android二维码扫描demo,亲测可行,简单易移植 * 1、 生成二维码:Bitmap mBitmap = EncodingHandler.createQRCode("www.baidu.com", 300);//300表示宽高 * 2、 扫描二维码:Intent intent = new Intent(MainActivity.this, CaptureActivity.class); * startActivityForResult(intent, REQUEST_CODE); * 3、 扫描结果回调,重写方法onActivityResult: * /@Override * protected void onActivityResult(int requestCode, int resultCode, Intent data) { * super.onActivityResult(requestCode, resultCode, data); * if (resultCode == RESULT_OK) { //RESULT_OK = -1 * Bundle bundle = data.getExtras(); * String scanResult = bundle.getString("result"); * Toast.makeText(MainActivity.this, scanResult, Toast.LENGTH_LONG).show(); * } * } * } * 4、 CameraManager getFramingRect()方法,定义了扫描的区域,可以自己修改。 * 5、 ViewfinderView ZXing扫码窗口的绘制。 * 6、 private void drawTextInfo(Canvas canvas, Rect frame) 修改文本绘制的位置 * 7、 private void drawLaserScanner(Canvas canvas, Rect frame) * 修改扫描线的样式。注意若使用paint.setShader(Shader shader) 方法,一定要在绘制完成后调用paint.setShader(null)。以免绘制信息出错。 * * 8、 CameraConfigurationManager 修改横竖屏、处理变形效果的核心类。 * 9、 DecodeHandler.decode ZXing解码的核心类 * 10、CaptureActivityHandler 当DecodeHandler.decode完成解码后,系统会向CaptureActivityHandler发消息。如果编码成功则调用CaptureActivity.handleDecode方法对扫描到的结果进行分类处理。

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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