我在中心看到很少有带公司徽标的二维码。是否可以在Android中生成带有任何徽标的QR码?如果可能,请详细解释这样做的方式。目前我正在使用Zxing生成QR码。
答案 0 :(得分:5)
参考Generating a qr code with a logo提供的指南和源代码 请找到我用来在Android上获得类似结果的示例Android代码。
我确信这段代码可以通过使用Paint类进行优化,特别是关于图像叠加不透明度,但此代码在这方面有效。
/**
* Writes the given Overlay on a new Bitmap object.
* @param Bitmap the Bitmap to overlay.
* @return the new {@link Bitmap}-object.
*/
public static Bitmap overlayBitmap(Bitmap overlay) {
BitMatrix matrix = null;
QRCodeWriter writer = new QRCodeWriter();
//Error correction
//Sometimes your QRCode will get damaged or covered up by something – like an image overlay for instance –
//therefore the designers of the QRCode has added four levels; 7% (L), 15 % (M), 25% (Q), 30% (H) of error
//correction were a error correction of level H should result in a QRCode that are still valid even when it’s
//30% obscured – for more info on error correction check this
Map<EncodeHintType, Object> hints;
hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//create qr code matrix
writer = new QRCodeWriter();
try {
matrix = writer.encode(redirectUrl,
BarcodeFormat.QR_CODE,
QRCODE_IMAGE_WIDTH,
QRCODE_IMAGE_HEIGHT,
hints);
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap image = toBitmap(matrix);
int height = image.getHeight();
int width = image.getWidth();
Bitmap combined = Bitmap.createBitmap(width, height, image.getConfig());
Canvas canvas = new Canvas(combined);
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
canvas.drawBitmap(image, new Matrix(), null);
int centreX = (canvasWidth - overlay.getWidth()) /2;
int centreY = (canvasHeight - overlay.getHeight()) /2 ;
//http://stackoverflow.com/a/12235235/1635441
//http://stackoverflow.com/a/5119093/1635441
//Paint p = new Paint();
//p.setXfermode(new PorterDuffXfermode(Mode.DST_ATOP)); //http://stackoverflow.com/a/17553502/1635441
//p.setAlpha(180);
//p.setARGB(a, r, g, b);
//canvas.drawBitmap(bitmapToBeOverlay, 0, 0, p);
//canvas.drawBitmap(overlay, new Matrix(), null);
canvas.drawBitmap(overlay, centreX, centreY, null);
return combined;
}
/**
* Writes the given Matrix to a new colour Bitmap object.
* @param matrix the matrix to write.
* @param Color the Color to be added.
* @return the new {@link Bitmap}-object.
*/
public static Bitmap toBitmapColour(BitMatrix matrix, int colour){
int height = matrix.getHeight();
int width = matrix.getWidth();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
bmp.setPixel(x, y, matrix.get(x,y) ? colour : Color.WHITE);
}
}
return bmp;
}
HTH
答案 1 :(得分:4)
QR码是快速响应代码,您可以使用zxing制作QR码。但默认情况下,中心或任何其他部分没有公司徽标。您可以做的是创建一个二维码,并在其上绘制公司的徽标图像
答案 2 :(得分:0)
您可以在中心制作带有背景徽标的二维码
首先使用以下代码生成QRCodeEncoder类:
public final class QRCodeEncoder {
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
private int dimension = Integer.MIN_VALUE;
private String contents = null;
private String displayContents = null;
private String title = null;
private BarcodeFormat format = null;
private boolean encoded = false;
public QRCodeEncoder(String data, Bundle bundle, String type,
String format, int dimension) {
this.dimension = dimension;
encoded = encodeContents(data, bundle, type, format);
}
public String getContents() {
return contents;
}
public String getDisplayContents() {
return displayContents;
}
public String getTitle() {
return title;
}
private boolean encodeContents(String data, Bundle bundle, String type,
String formatString) {
// Default to QR_CODE if no format given.
format = null;
if (formatString != null) {
try {
format = BarcodeFormat.valueOf(formatString);
} catch (IllegalArgumentException iae) {
// Ignore it then
}
}
if (format == null || format == BarcodeFormat.QR_CODE) {
this.format = BarcodeFormat.QR_CODE;
encodeQRCodeContents(data, bundle, type);
} else if (data != null && data.length() > 0) {
contents = data;
displayContents = data;
title = "Text";
}
return contents != null && contents.length() > 0;
}
private void encodeQRCodeContents(String data, Bundle bundle, String type) {
if (type.equals(Contents.Type.TEXT)) {
if (data != null && data.length() > 0) {
contents = data;
displayContents = data;
title = "Text";
}
} else if (type.equals(Contents.Type.EMAIL)) {
data = trim(data);
if (data != null) {
contents = "mailto:" + data;
displayContents = data;
title = "E-Mail";
}
} else if (type.equals(Contents.Type.PHONE)) {
data = trim(data);
if (data != null) {
contents = "tel:" + data;
displayContents = PhoneNumberUtils.formatNumber(data);
title = "Phone";
}
} else if (type.equals(Contents.Type.SMS)) {
data = trim(data);
if (data != null) {
contents = "sms:" + data;
displayContents = PhoneNumberUtils.formatNumber(data);
title = "SMS";
}
} else if (type.equals(Contents.Type.CONTACT)) {
if (bundle != null) {
StringBuilder newContents = new StringBuilder(100);
StringBuilder newDisplayContents = new StringBuilder(100);
newContents.append("MECARD:");
String name = trim(bundle
.getString(ContactsContract.Intents.Insert.NAME));
if (name != null) {
newContents.append("N:").append(escapeMECARD(name))
.append(';');
newDisplayContents.append(name);
}
String address = trim(bundle
.getString(ContactsContract.Intents.Insert.POSTAL));
if (address != null) {
newContents.append("ADR:").append(escapeMECARD(address))
.append(';');
newDisplayContents.append('\n').append(address);
}
Collection<String> uniquePhones = new HashSet<String>(
Contents.PHONE_KEYS.length);
for (int x = 0; x < Contents.PHONE_KEYS.length; x++) {
String phone = trim(bundle
.getString(Contents.PHONE_KEYS[x]));
if (phone != null) {
uniquePhones.add(phone);
}
}
for (String phone : uniquePhones) {
newContents.append("TEL:").append(escapeMECARD(phone))
.append(';');
newDisplayContents.append('\n').append(
PhoneNumberUtils.formatNumber(phone));
}
Collection<String> uniqueEmails = new HashSet<String>(
Contents.EMAIL_KEYS.length);
for (int x = 0; x < Contents.EMAIL_KEYS.length; x++) {
String email = trim(bundle
.getString(Contents.EMAIL_KEYS[x]));
if (email != null) {
uniqueEmails.add(email);
}
}
for (String email : uniqueEmails) {
newContents.append("EMAIL:").append(escapeMECARD(email))
.append(';');
newDisplayContents.append('\n').append(email);
}
String url = trim(bundle.getString(Contents.URL_KEY));
if (url != null) {
// escapeMECARD(url) -> wrong escape e.g.
// http\://zxing.google.com
newContents.append("URL:").append(url).append(';');
newDisplayContents.append('\n').append(url);
}
String note = trim(bundle.getString(Contents.NOTE_KEY));
if (note != null) {
newContents.append("NOTE:").append(escapeMECARD(note))
.append(';');
newDisplayContents.append('\n').append(note);
}
// Make sure we've encoded at least one field.
if (newDisplayContents.length() > 0) {
newContents.append(';');
contents = newContents.toString();
displayContents = newDisplayContents.toString();
title = "Contact";
} else {
contents = null;
displayContents = null;
}
}
} else if (type.equals(Contents.Type.LOCATION)) {
if (bundle != null) {
// These must use Bundle.getFloat(), not getDouble(), it's part
// of the API.
float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
contents = "geo:" + latitude + ',' + longitude;
displayContents = latitude + "," + longitude;
title = "Location";
}
}
}
}
public Bitmap encodeAsBitmap() throws WriterException {
if (!encoded)
return null;
Hashtable hints = null;
String encoding = guessAppropriateEncoding(contents);
if (encoding != null) {
hints = new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
MultiFormatWriter writer = new MultiFormatWriter();
ByteMatrix result = writer.encode(contents, format, dimension,dimension, hints);
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
// All are 0, or black, by default
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
if (result.get(x, y) == 0) {
pixels[offset + x] = BLACK;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
private static String guessAppropriateEncoding(CharSequence contents) {
// Very crude at the moment
for (int i = 0; i < contents.length(); i++) {
if (contents.charAt(i) > 0xFF) {
return "UTF-8";
}
}
return null;
}
private static String trim(String s) {
if (s == null) {
return null;
}
String result = s.trim();
return result.length() == 0 ? null : result;
}
private static String escapeMECARD(String input) {
if (input == null || (input.indexOf(':') < 0 && input.indexOf(';') < 0)) {
return input;
}
int length = input.length();
StringBuilder result = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = input.charAt(i);
if (c == ':' || c == ';') {
result.append('\\');
}
result.append(c);
}
return result.toString();
}
}
在您希望使用图像制作QR码的欲望活动中使用波纹管代码:
private Bitmap generateQRCode(String encryptData) {
// here encryptData data will be your data
WindowManager manager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int width = point.x;
int height = point.y;
int smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 3 / 4;
// Encode with a QR Code image
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(encryptData, null, Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), smallerDimension);
Bitmap bitmap = null;
Bitmap bitMerged = null;
try {
bitmap = qrCodeEncoder.encodeAsBitmap();
Bitmap myLogo = BitmapFactory.decodeResource(getResources(), R.drawable.pay365logo);
bitMerged = mergeBitmaps(bitmap,myLogo);
} catch (WriterException e) {
e.printStackTrace();
}
return bitMerged;
}
public static Bitmap mergeBitmaps(Bitmap qrCode, Bitmap myLogo) {
Bitmap bmOverlay = Bitmap.createBitmap(qrCode.getWidth(), qrCode.getHeight(), qrCode.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(myLogo, (qrCode.getWidth() - myLogo.getWidth()) / 2, (qrCode.getHeight() - myLogo.getHeight()) / 2, null);
canvas.drawBitmap(qrCode, new Matrix(), null);
return bmOverlay;
}
答案 3 :(得分:0)
这是一个诀窍,实际上您的QR码生成器(如果您使用zxing)返回位图值,因此您可以将 QR码位图与徽标位图合并,这是一个例子:
首先,您必须无效才能合并两个位图并调整徽标大小,以便将其放在QR码的中心
public Bitmap mergeBitmaps(Bitmap logo, Bitmap qrcode) {
Bitmap combined = Bitmap.createBitmap(qrcode.getWidth(), qrcode.getHeight(), qrcode.getConfig());
Canvas canvas = new Canvas(combined);
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
canvas.drawBitmap(qrcode, new Matrix(), null);
Bitmap resizeLogo = Bitmap.createScaledBitmap(logo, canvasWidth / 5, canvasHeight / 5, true);
int centreX = (canvasWidth - resizeLogo.getWidth()) /2;
int centreY = (canvasHeight - resizeLogo.getHeight()) / 2;
canvas.drawBitmap(resizeLogo, centreX, centreY, null);
return combined;
}
然后使用该空格合并QR码位图和徽标位图,并将其推入图像视图
Bitmap yourLogo = BitmapFactory.decodeResource(getResources(), R.drawable.your_logo);
Bitmap merge = mergeBitmaps(yourLogo, qrcode_bitmap);
yourImageView.setImageBitmap(merge);