I have seen few QR codes with company logo at the center. Is it possible to generate a QR code with a any logo in android? If possible kindly explain the way for doing it. Currently I am using Zxing for generating QR codes.
-
Possible duplicate of [Is there a library to create Design QR codes with Java?](http://stackoverflow.com/questions/4322881/is-there-a-library-to-create-design-qr-codes-with-java) – rds Feb 14 '16 at 15:46
4 Answers
It's a trick to do this, actually your QR Code generator (if you using zxing) return a bitmap value, so you can merge your QR Code bitmap with your logo bitmap, and here is an example:
First, you must have void to merge two bitmap and resize the logo so you can fit it at the center of the QR Code
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;
}
Then you use that void to merge your QR Code bitmap and your logo bitmap and push it in to your image view
Bitmap yourLogo = BitmapFactory.decodeResource(getResources(), R.drawable.your_logo);
Bitmap merge = mergeBitmaps(yourLogo, qrcode_bitmap);
yourImageView.setImageBitmap(merge);

- 113
- 1
- 8
A QR code is a quick response code, You can use zxing to make the QR codes. but by default there are no company logos present there at center or any other part. What you can do is create a QR code and on top of it draw the logo image of the company

- 5,148
- 5
- 40
- 61
-
5@PoweRoy Place it in center as a small image it should work fine, Create an image like that and scan it to check it works or not – Girish Nair Nov 06 '12 at 10:13
-
@Stella: I tired scanning with few QR code apps, it doesn't seem to be standard QR code in any manner, It might be some custom encoding mechanism – Girish Nair Jul 28 '16 at 13:12
With reference to the guide and source code provided at Generating a qr code with a logo please find the sample Android code that I use to achieve similar result on Android.
I am sure that this code can be optimised, specifically with regards to image overlay opacity by making use of the Paint class but this code works effectively in this regard.
/**
* 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

- 300
- 1
- 6
- 16
-
Pasting the image is not a good option. I tried your code. My QR code get messed up when I paste image on top of generated QR Code. – Sanjay Kumar Jan 18 '15 at 07:16
-
This is not a good solution, because you always have to check manually - if the QR-code still works after overlaying it with an image – Alexander Farber Jun 26 '15 at 09:05
-
2Works like a charm..At least when scanning with Zxing. Remember to set the ErrorCorrectionLevel to H – guy_m Aug 21 '15 at 11:49
You can make QR code with background logo in center
First make a QRCodeEncoder class with bellow code:
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();
}
}
Than use bellow code inside your desire activity where you want to make QR Code with image:
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;
}

- 49
- 1
- 5