如何在android中为QR码添加徽标

时间:2012-11-06 09:05:56

标签: android zxing

我在中心看到很少有带公司徽标的二维码。是否可以在Android中生成带有任何徽标的QR码?如果可能,请详细解释这样做的方式。目前我正在使用Zxing生成QR码。

4 个答案:

答案 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;
}

会是这样的: It will be like this

答案 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);