ZXing을 사용하여 Android에서 QR 코드 생성(로고 패턴 추가 지원)
ZXing은 QR 코드를 생성하고 스캔하는 데 사용할 수 있는 Google의 오픈 소스 라이브러리입니다. 이 글은 첫 번째 부분을 소개합니다.
우선 렌더링은 다음과 같습니다.
다양한 ZXing 관련 파일 공식 다운로드 주소: https://github.com/zxing/zxing /releases
또는 여기에서 다운로드하세요(이 프로젝트에 사용된 jar 패키지만, 버전 번호: 3.2.0): 링크: http://pan.baidu.com/s/1pLqAR5x
1. 2개의 QR 코드 도구 클래스
/** * 二维码生成工具类 */ public class QRCodeUtil { /** * 生成二维码Bitmap * * @param content 内容 * @param widthPix 图片宽度 * @param heightPix 图片高度 * @param logoBm 二维码中心的Logo图标(可以为null) * @param filePath 用于存储二维码图片的文件路径 * @return 生成二维码及保存文件是否成功 */ public static boolean createQRImage(String content, int widthPix, int heightPix, Bitmap logoBm, String filePath) { try { if (content == null || "".equals(content)) { return false; } //配置参数 Map<encodehinttype, object=""> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //容错级别 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //设置空白边距的宽度 // hints.put(EncodeHintType.MARGIN, 2); //default is 4 // 图像数据转换,使用了矩阵转换 BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints); int[] pixels = new int[widthPix * heightPix]; // 下面这里按照二维码的算法,逐个生成二维码的图片, // 两个for循环是图片横列扫描的结果 for (int y = 0; y < heightPix; y++) { for (int x = 0; x < widthPix; x++) { if (bitMatrix.get(x, y)) { pixels[y * widthPix + x] = 0xff000000; } else { pixels[y * widthPix + x] = 0xffffffff; } } } // 生成二维码图片的格式,使用ARGB_8888 Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix); if (logoBm != null) { bitmap = addLogo(bitmap, logoBm); } //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大! return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath)); } catch (WriterException | IOException e) { e.printStackTrace(); } return false; } /** * 在二维码中间添加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; } }</encodehinttype,>
를 생성합니다. 2. 활동에 사용:
/** * 二维码生成 */ public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //内容 final EditText contentET = (EditText) findViewById(R.id.create_qr_content); //显示二维码图片 final ImageView imageView = (ImageView) findViewById(R.id.create_qr_iv); //是否添加Logo final CheckBox addLogoCB = (CheckBox) findViewById(R.id.create_qr_addLogo); Button createQrBtn = (Button) findViewById(R.id.create_qr_btn); createQrBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String filePath = getFileRoot(MainActivity.this) + File.separator + "qr_" + System.currentTimeMillis() + ".jpg"; //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中 new Thread(new Runnable() { @Override public void run() { boolean success = QRCodeUtil.createQRImage(contentET.getText().toString().trim(), 800, 800, addLogoCB.isChecked() ? BitmapFactory.decodeResource(getResources(), R.mipmap.qr_logo) : null, filePath); if (success) { runOnUiThread(new Runnable() { @Override public void run() { imageView.setImageBitmap(BitmapFactory.decodeFile(filePath)); } }); } } }).start(); } }); } //文件存储根目录 private String getFileRoot(Context context) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File external = context.getExternalFilesDir(null); if (external != null) { return external.getAbsolutePath(); } } return context.getFilesDir().getAbsolutePath(); } }
/** * 二维码生成 */ public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //内容 final EditText contentET = (EditText) findViewById(R.id.create_qr_content); //显示二维码图片 final ImageView imageView = (ImageView) findViewById(R.id.create_qr_iv); //是否添加Logo final CheckBox addLogoCB = (CheckBox) findViewById(R.id.create_qr_addLogo); Button createQrBtn = (Button) findViewById(R.id.create_qr_btn); createQrBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String filePath = getFileRoot(MainActivity.this) + File.separator + "qr_" + System.currentTimeMillis() + ".jpg"; //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中 new Thread(new Runnable() { @Override public void run() { boolean success = QRCodeUtil.createQRImage(contentET.getText().toString().trim(), 800, 800, addLogoCB.isChecked() ? BitmapFactory.decodeResource(getResources(), R.mipmap.qr_logo) : null, filePath); if (success) { runOnUiThread(new Runnable() { @Override public void run() { imageView.setImageBitmap(BitmapFactory.decodeFile(filePath)); } }); } } }).start(); } }); } //文件存储根目录 private String getFileRoot(Context context) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File external = context.getExternalFilesDir(null); if (external != null) { return external.getAbsolutePath(); } } return context.getFilesDir().getAbsolutePath(); } }
3. 이 프로젝트의 이미지 파일은
context.getExternalFilesDir(null)
디렉터리에 저장됩니다. 공식 API 문서에 따르면 KitKat(Android 4.4)부터 이 디렉터리에 파일을 저장하는 데에는 SD 카드 읽기 및 쓰기 권한이 필요하지 않습니다. 그러나 테스트에 따르면 Redmi Note 및 Meizu MX3(시스템은 모두 Android 4.4.4)에서는 실제로 권한이 필요하지 않지만 Huawei P6(Android 4.4.2)에서는 파일을 성공적으로 저장하려면 권한을 선언해야 합니다. 즉, 매니페스트에 다음 콘텐츠를 추가해야 합니다.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission></uses-permission>
따라서 개인적으로 Android 4.4.4부터는 소위 권한이 필요하지 않다고 생각합니다.
이제 Android에서 QR 코드를 생성하고 로고를 추가하는 코드를 공유하겠습니다.
구체적인 코드는 다음과 같습니다.
@Override public Bitmap generateBitmap(String content, int width, int height) { QRCodeWriter qrCodeWriter = new QRCodeWriter(); Map<EncodeHintType, String> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//默认 hints.put(EncodeHintType.MARGIN, "1");//无白色边框 try { BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints); int[] pixels = new int[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (encode.get(j, i)) { pixels[i * width + j] = 0x00000000; } else { pixels[i * width + j] = 0xffffffff; } } } return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565); } catch (WriterException e) { e.printStackTrace(); } return null; } @Override public Bitmap addLogo(Bitmap qrBitmap, Bitmap logoBitmap) { int qrBitmapWidth = qrBitmap.getWidth(); int qrBitmapHeight = qrBitmap.getHeight(); int logoBitmapWidth = logoBitmap.getWidth(); int logoBitmapHeight = logoBitmap.getHeight(); Bitmap blankBitmap = Bitmap.createBitmap(qrBitmapWidth, qrBitmapHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(blankBitmap); canvas.drawBitmap(qrBitmap, 0, 0, null); canvas.save(Canvas.ALL_SAVE_FLAG); float scaleSize = 1.0f; while ((logoBitmapWidth / scaleSize) > (qrBitmapWidth / 3.5) || (logoBitmapHeight / scaleSize) > (qrBitmapHeight / 3.5)) { scaleSize *= 2; } float sx = 1.0f / scaleSize; canvas.scale(sx, sx, qrBitmapWidth / 2, qrBitmapHeight / 2); canvas.drawBitmap(logoBitmap, (qrBitmapWidth - logoBitmapWidth) / 2, (qrBitmapHeight - logoBitmapHeight) / 2, null); canvas.restore(); return blankBitmap; }
자, 코드는 여기 있습니다. , 모두에게 도움이 되기를 바랍니다!
ZXing을 사용하여 Android에서 QR 코드 생성(로고 패턴 추가 지원)에 대한 더 많은 관련 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











일부 애플리케이션이 제대로 작동하지 않는 회사의 보안 소프트웨어에 대한 문제 해결 및 솔루션. 많은 회사들이 내부 네트워크 보안을 보장하기 위해 보안 소프트웨어를 배포 할 것입니다. ...

시스템 도킹의 필드 매핑 처리 시스템 도킹을 수행 할 때 어려운 문제가 발생합니다. 시스템의 인터페이스 필드를 효과적으로 매핑하는 방법 ...

데이터베이스 작업에 MyBatis-Plus 또는 기타 ORM 프레임 워크를 사용하는 경우 엔티티 클래스의 속성 이름을 기반으로 쿼리 조건을 구성해야합니다. 매번 수동으로 ...

IntellijideAultimate 버전을 사용하여 봄을 시작하십시오 ...

많은 응용 프로그램 시나리오에서 정렬을 구현하기 위해 이름으로 이름을 변환하는 솔루션, 사용자는 그룹으로, 특히 하나로 분류해야 할 수도 있습니다.

Java 객체 및 배열의 변환 : 캐스트 유형 변환의 위험과 올바른 방법에 대한 심층적 인 논의 많은 Java 초보자가 객체를 배열로 변환 할 것입니다 ...

Redis 캐싱 솔루션은 제품 순위 목록의 요구 사항을 어떻게 인식합니까? 개발 과정에서 우리는 종종 a ... 표시와 같은 순위의 요구 사항을 처리해야합니다.

그룹 내에서 정렬을 구현하기 위해 이름을 숫자로 변환하는 방법은 무엇입니까? 그룹으로 사용자를 정렬 할 때는 종종 사용자 이름을 숫자로 변환하여 다르게 만들 수 있습니다 ...
