@二维码生成

个性二维码

第一次接触二维码开发,对二维码刚有所了解的时候,就得到要做个性二维码 的需求。看着网络上的个性二维码,陷入了沉思。 心里千万遍问自己,这到底是什么实现原理呢?后面找来找去,各种资料都翻上来了:在朋友的帮助下,找到一篇有用的文章,并在此文章的引导下,完成了个性二维码的开发。感谢作者。即下发的原理参考链接

原理参考

链接: link.

图片参考:

代码片

上面原理参考有了大体实现原理的代码了,但是还漏了三四个方法,花了两天白了头给补上了。。。
(File 对应后台传过来的图片,我这边给转成file文件使用)

/**绘制个性二维码*/public Bitmap createAreBitmap(Context context, String str, int width, boolean isDeleteWhiteGap,ErrorCorrectionLevel level,List<ArtQrcodeBean> artQrcodeBeans)throws WriterException, NullPointerException {Hashtable<EncodeHintType, Object> hints = new Hashtable<>();if (null != level) {hints.put(EncodeHintType.ERROR_CORRECTION, level);// 指定纠错等级}hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");//指定编码格式if (TextUtils.isEmpty(str)) {return null;}if (matrix == null){matrix = new QRCodeWriter().encode(str, BarcodeFormat.QR_CODE,0, 0, hints);if (isDeleteWhiteGap) {matrix = deleteWhite(matrix);//删除白边}}if (formatBitMatrix(matrix)){this.artQrcodeBeans = artQrcodeBeans;int codeWidth = width/codeNumPerLine;int remainder = width%codeNumPerLine;int matrixWidth = width;if (remainder > 0){//调整初始图片的宽度,凑整,让每个码元点占用整数个像素点codeWidth++;matrixWidth = codeWidth*codeNumPerLine;}judgeRule();getAllRects();searchfRect();Bitmap bitmap = Bitmap.createBitmap(matrixWidth,matrixWidth, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);Paint paint = new Paint();paint.setColor(Color.WHITE);canvas.drawRect(0,0,bitmap.getWidth(),bitmap.getHeight(),paint);codeUnit = codeWidth;drawPicture(canvas,paint,codeWidth);Bitmap bitmap1 = Bitmap.createBitmap(bitmap.getWidth()-codeWidth,bitmap.getHeight()-codeWidth, Bitmap.Config.ARGB_8888);Canvas canvas1 = new Canvas(bitmap1);canvas1.drawBitmap(bitmap,0,0,null);return  bitmap1;}return  null;}
/*** 格式化BitMatrix,找出其中所有的码元点* @param bitMatrix* @return*/private boolean formatBitMatrix(BitMatrix bitMatrix){boolean success = false;int matrixLength = bitMatrix.getWidth();int matrixHeight = bitMatrix.getHeight();if (matrixLength == matrixHeight && matrixLength>(LOCATOR_WIDTH+1)*2){success = true;codeNumPerLine = matrixLength;leftLocator.set(0,0,LOCATOR_WIDTH,LOCATOR_WIDTH);rightLocator.set(matrixLength-LOCATOR_WIDTH-codeUnit,0,matrixLength,LOCATOR_WIDTH);bottomLocator.set(0,matrixLength-LOCATOR_WIDTH-codeUnit,LOCATOR_WIDTH,matrixLength);//遍历,得出所有的码元for (int x = 0; x < matrixLength; x++) {StringBuilder sb = new StringBuilder("列"+x);StringBuilder sb_p = new StringBuilder("point");//先列遍历,在行遍历for (int y = 0; y < matrixLength; y++) {//查看此element是否为有信息的码元点(二维码黑色部分)boolean info = bitMatrix.get(x,y);MyPoint point = new MyPoint(x,y);if (info){String pointStr = "["+y+","+x+"]";if (!isElementInRect(leftLocator,point) && !isElementInRect(rightLocator,point) &&!isElementInRect(bottomLocator,point) ){//以列优先的顺序存放,故需要把下标的行列反过来,便于操作int columnRow = y+x*matrixLength;//存储码元在可用码元矩阵中的列行坐标this.codeElements.put(columnRow,point);codeElementList.add(point);sb.append(pointStr);}else {sb_p.append(pointStr);}}}sb_p.append(" in locator");}}return success;}
/*** 遍历形状集合Shape,查找出所有的矩形框,将其中的码元标记为已发现,并添加到outElements集合里* @param shape*/
private void adjustRect(RectShape shape) {for (int i = 0; i < shape.getAllPoints().size(); i++) {for (int j = 0; j < codeElements.size(); j++) {if ( shape.getAllPoints().get(i).equals(codeElements.valueAt(j))){outElements.put(codeElements.keyAt(j),codeElements.valueAt(j));}}}
}private boolean containt(MyPoint point){if (point == null ||point.isAdd())return false;return codeElementList.contains(point) ;
}private void drawPicture( Canvas canvas, Paint paint ,int codeWidth) {//先画三个定位符Bitmap locatorBitmap = BitmapFactory.decodeFile(codeEyeFile.getAbsolutePath());Bitmap locatorIcon = Bitmap.createScaledBitmap(locatorBitmap,LOCATOR_WIDTH*codeWidth,LOCATOR_WIDTH*codeWidth,true);canvas.drawBitmap(locatorIcon, leftLocator.left*codeWidth,leftLocator.top*codeWidth,paint);canvas.drawBitmap(locatorIcon,rightLocator.left*codeWidth,rightLocator.top*codeWidth,paint);canvas.drawBitmap(locatorIcon,bottomLocator.left*codeWidth,bottomLocator.top*codeWidth,paint);Random rand = new Random();//再画找到的所有矩形框for (int index1 = 0; index1 < allRects.size(); index1++) {int shapeId = allRects.keyAt(index1);//key为此集合中相同的shapeIdSparseArray<MyPoint> rects = allRects.valueAt(index1);RectShape shape = SHAPES.get(shapeId);if (shape.getFileList()!= null && shape.getFileList().size() != 0){int size2 = rects != null?rects.size():0;List<Bitmap>   bitmaps1 = new ArrayList<>();for (int i = 0; i < shape.getFileList().size(); i++) {if (shape.getFileList().get(i)  != null){Bitmap bmp = BitmapFactory.decodeFile(shape.getFileList().get(i) .getAbsolutePath());Bitmap shapeIcon = Bitmap.createScaledBitmap(bmp,(int) shape.getWidth()*codeUnit,(int) shape.getHeight()*codeUnit,true);bitmaps1.add(shapeIcon);}}int num = 0;for (int index2 = 0; index2 < size2; index2++) {MyPoint point = rects.valueAt(index2);if (point != null){if (bitmaps1.size() != 1){num =  rand.nextInt(bitmaps1.size());}Bitmap bitmap = bitmaps1.get(num);canvas.drawBitmap(bitmap,point.x * codeUnit,point.y*codeUnit,paint);}}for (int i = 0; i < bitmaps1.size(); i++) {bitmaps1.get(i).recycle();}}}if ( fileType11List.size() != 0){//再画剩下的单个码元List<Bitmap> codeBitmaps = new ArrayList<>();for (int i = 0; i < fileType11List.size(); i++) {Bitmap singleBitmap = BitmapFactory.decodeFile(fileType11List.get(i).getAbsolutePath());Bitmap codeBmp = Bitmap.createScaledBitmap(singleBitmap,codeUnit,codeUnit,true);codeBitmaps.add(codeBmp);}int size = codeElements.size();int num = 0;for (int singleIndex = 0; singleIndex < size; singleIndex++) {MyPoint point = codeElements.valueAt(singleIndex);if (point != null){if (codeBitmaps.size() != 1){num =  rand.nextInt(codeBitmaps.size());}Bitmap bitmap = codeBitmaps.get(num);canvas.drawBitmap(bitmap,point.x * codeUnit,point.y*codeUnit,paint);}}for (int i = 0; i < codeBitmaps.size(); i++) {codeBitmaps.get(i).recycle();}System.gc();}
}/*除白边*/
private BitMatrix deleteWhite(BitMatrix matrix) {int[] rec = matrix.getEnclosingRectangle();int resWidth = rec[2] + 1;//右int resHeight = rec[3] + 1;//下BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);resMatrix.clear();for (int i = 0; i < resWidth; i++) {for (int j = 0; j < resHeight; j++) {if (matrix.get(i + rec[0], j + rec[1]))resMatrix.set(i, j);}}return resMatrix;
}
```javascript
public class MyPoint extends Point {private boolean isAdd = false;public MyPoint() {}public MyPoint(int x, int y) {super(x, y);}public MyPoint(@NonNull Point src) {super(src);}public boolean isAdd() {return isAdd;}public void setAdd(boolean add) {isAdd = add;}
}

不明白可以私我
源码下载

bean类等
public class ArtQrcodeBean implements Parcelable {
private Bitmap codeEyeBitmap;
private String img_url;
private int rule;
private Bitmap bitmap;

protected ArtQrcodeBean(Parcel in) {codeEyeBitmap = in.readParcelable(Bitmap.class.getClassLoader());img_url = in.readString();rule = in.readInt();bitmap = in.readParcelable(Bitmap.class.getClassLoader());
}public static final Creator<ArtQrcodeBean> CREATOR = new Creator<ArtQrcodeBean>() {@Overridepublic ArtQrcodeBean createFromParcel(Parcel in) {return new ArtQrcodeBean(in);}@Overridepublic ArtQrcodeBean[] newArray(int size) {return new ArtQrcodeBean[size];}
};public Bitmap getBitmap() {return bitmap;
}public void setBitmap(Bitmap bitmap) {this.bitmap = bitmap;
}public String getImg_url() {return img_url;
}public void setImg_url(String img_url) {this.img_url = img_url;
}public int getRule() {return rule;
}public void setRule(int rule) {this.rule = rule;
}public Bitmap getCodeEyeBitmap() {return codeEyeBitmap;
}public void setCodeEyeBitmap(Bitmap codeEyeBitmap) {this.codeEyeBitmap = codeEyeBitmap;
}@Override
public int describeContents() {return 0;
}@Override
public void writeToParcel(Parcel dest, int flags) {dest.writeParcelable(codeEyeBitmap, flags);dest.writeString(img_url);dest.writeInt(rule);dest.writeParcelable(bitmap, flags);
}

}

public class RectShape extends Shape {
private RectF mRect = new RectF();

public RectShape() {}@Override
public void draw(Canvas canvas, Paint paint) {canvas.drawRect(mRect, paint);
}@Override
public void getOutline(Outline outline) {final RectF rect = rect();outline.setRect((int) Math.ceil(rect.left), (int) Math.ceil(rect.top),(int) Math.floor(rect.right), (int) Math.floor(rect.bottom));
}/*** chf* TYPE_33:指代 x轴3个点,y轴3个点的矩阵*/
private int resID;

// private File file;
private List bitmapList;
private int type;
public static final int TYPE_32 = 32;
public static final int TYPE_23 = 23;
public static final int TYPE_22 = 22;
public static final int TYPE_12 = 12;
public static final int TYPE_13 = 13;
public static final int TYPE_21 = 21;
public static final int TYPE_31 = 31;
public static final int TYPE_41 = 41;
public static final int TYPE_14 = 14;
private List allPoints = new ArrayList<>();

// public File getFile() {
// return file;
// }
//
// public void setFile(File file) {
// this.file = file;
// }

public List<Bitmap> getBitmapList() {return bitmapList;
}public void setBitmapList(List<Bitmap> bitmapList) {this.bitmapList = bitmapList;
}public int getResID() {return resID;
}public void setResID(int resID) {this.resID = resID;
}public int getType() {return type;
}public void setType(int type) {this.type = type;
}public List<MyPoint> getAllPoints() {return allPoints;
}public void setAllPoints(List<MyPoint> allPoints) {this.allPoints = allPoints;
}@Override
protected void onResize(float width, float height) {mRect.set(0, 0, width, height);
}/*** Returns the RectF that defines this rectangle's bounds.*/
protected final RectF rect() {return mRect;
}@Override
public RectShape clone() throws CloneNotSupportedException {final RectShape shape = (RectShape) super.clone();shape.mRect = new RectF(mRect);return shape;
}@Override
public boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}if (!super.equals(o)) {return false;}RectShape rectShape = (RectShape) o;return Objects.equals(mRect, rectShape.mRect);
}@Override
public int hashCode() {return Objects.hash(super.hashCode(), mRect);
}

}

个性二维码生成(android开发)相关推荐

  1. Android开发——Android中的二维码生成与扫描

    0. 前言 今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描.本篇旨在帮助有需求的同学快速完成二维 ...

  2. 玩转Android之二维码生成与识别

    二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了.那么今天我们就来看看怎么样在我们自己的App中集成二维码的 ...

  3. Android 二维码 生成和识别

    今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS.Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术 ...

  4. Android 二维码 生成和识别(附Demo源码)

    Posted on 2013-08-25 23:15 泡泡糖 阅读( 20424) 评论( 7) 编辑 收藏 今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管 ...

  5. Android之二维码生成与识别 读取相册

    二维码生成与扫描 转自http://blog.csdn.net/u012702547/article/details/51501350 读取相册二维码 转自http://blog.csdn.net/a ...

  6. Android之二维码生成与扫描

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428 本文出自:[顾林海的博客] ##前言 月底离开公司,准备 ...

  7. Java 快速开发二维码生成服务

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「码农小胖哥」 1. 前言 不知道从什么 ...

  8. python myqr制作二维码生成器_用Python生成动态二维码,只要5行代码,拥有你的个性二维码!...

    原标题:用Python生成动态二维码,只要5行代码,拥有你的个性二维码! 前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. P ...

  9. [2021]Linux下C语言qrencode二维码生成库的基本使用和ARM开发板移植

    文章目录 一.前言 二.准备所用到的环境以及版本信息 1.Ubuntu和内核版本 2.gcc和g++版本 3.交叉编译gcc和g++版本 4.开发板信息 三.开发环境编译&安装qrencode ...

最新文章

  1. 5-MST 多生成树 //IOU模拟
  2. Django搭建个人博客(二)
  3. 《图解密码技术》分组密码(1) 概览
  4. SpringMVC快速入门-开发步骤
  5. android ui布局适配,Android适配全面总结(一)----屏幕适配
  6. PHP简单操作Excel
  7. c语言库文件是dll还是lib,C语言之静态链接库与动态链接库(2)
  8. 使用android快速开发框架afinal的FinalDb操作android数据库
  9. Eureka-zookeeper的服务发现替代方案
  10. go list指针_「GCTT 出品」Go 语言机制之内存剖析
  11. [转载] Java中使用new构造数组时会不会自动调用类的默认构造函数
  12. 【书籍推荐】《美国黒室》
  13. mysql基础之mariadb概念
  14. matlab调用python数值精度改变吗_Matlab如何调用python脚本-matlab调用python数值精度改变吗 - PS下...
  15. 知我者谓我心忧 不知我者谓我何求
  16. u盘文件突然不见了怎么样才能恢复呢?
  17. TestNG-学习笔记
  18. 【CTF WriteUp】网鼎杯 青龙组 Misc题解复现(整理,WP非原创)
  19. 关于HMC5883L驱动书写及调试的总结
  20. 视频教程-通俗易懂的SVN入门教程(含配套资料)-Java

热门文章

  1. Python中用turtle库画旋涡
  2. 鸽子学Python 之 Pandas数据分析库
  3. 基金 thread.php,这个时候,我们可以为基金“上会通过”做点什么?(附方案) - 基金申请 - 小木虫 - 学术 科研 互动社区...
  4. 《儿科护理学(护理本)》
  5. python的简单使用_用python简单处理图片
  6. JAVA生成二维码(一)
  7. 教你如何用FVD Downloader下载在线视频
  8. P4844 LJJ爱数数
  9. 教师节:这才是真正的老师
  10. 三分钟轻松实现连接西门子PLC