Create QR Code with Logo in android

Qr code with logo logicchip thumb

Creating Qr code with logo using zxing library. In the first place QR code (abbreviated from Quick Response Code) is the trademark for a type of matrix barcode (or two-dimensional barcode). Not to mention it’s first designed for the automotive industry in Japan. On the other hand a barcode is a machine-readable optical label that contains information about the item to which it is attached. In fact a QR code uses four standardized encoding modes (numeric, alphanumeric, byte/binary, and kanji) .To efficiently store data,extensions may also be used.

Here we are using zxing library to make the QR codes. But by default there are no company logos present there at center or any other part. Furthermore what you can do is create a QR code and on top of it draw the logo image of the company. In fact that’s exactly what we are going to do Creating qr code with logo and custom color. Above all include zxing core in your dependencies. Further information is available at previous post Qr Code Reader And Qr Code Generator for Android.

dependencies {
..............
.......
    compile 'com.google.zxing:core:3.3.0'
}

 

As a matter of fact a good amount of library’s are available for making Qr Code. Still it’s better to stick with native library’s or create your own library’s. Making Qr code with logo is good and bad at the same time. In fact it’s good for promoting and identifying and bad for some Qr readers, it wont read your code. As a result of trial and error generate combination of white, wherever white is that the background color just like the figure. Otherwise Qr readers will not acknowledge your code.

Download full source code here.

Furthermore consider the below figure. Accordingly first one is basic Qr code with low error correction level. Thus the second one is Qr code with custom logo, color and high error correction.

Qr code with logo logicchip1

Setting parameters for Qr Code.

As a matter of fact Qr code require some parameters before creating. Accordingly data to encode, character set, error correction level, height and width. So data to encode is the string or message we pass. Then the character set  UTF-8 which is defined by Unicode. Finally error correction is an important aspect. Even so four types of error correction levels are present Level L(L), Level M(M), Level Q(Q) and Level H(H). Hence it can restore approximately  7% , 15% ,25% , 30% of code words respectively.

public void GenerateClick(View view){
        try {
            //setting size of qr code
            int width =300,height = 300;
            int smallestDimension = width < height ? width : height;

            EditText editText=(EditText)findViewById(R.id.editText) ;
            String qrCodeData = editText.getText().toString();
            //setting parameters for qr code
            String charset = "UTF-8"; 
            Map<EncodeHintType, ErrorCorrectionLevel> hintMap =new HashMap<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            CreateQRCode(qrCodeData, charset, hintMap, smallestDimension, smallestDimension);

        } catch (Exception ex) {
            Log.e("QrGenerate",ex.getMessage());
        }
    }

Generating Qr Code.

Generated Qr code is in BitMatrix format so it’s convert to bitmap for our purpose. However custom color can be applied in the conversion process. At the same time where  BitMatrix to Bitmap take place. Furthermore that part is mentioned in the code with comments. Therefore read the comments to know what’s happening. Also the logo for merging is fetched here. To clarify actual process behind the conversion to bitmap is, Checking each bitmatrix pixel position by position. Thus the result is placed inside an integer array. Those results are checked before inserting .Data representing bit is placed with black and data nil bit is with white, but here its different because the black color is replaced with our custom color.

 public  void CreateQRCode(String qrCodeData, String charset, Map hintMap, int qrCodeheight, int qrCodewidth){
    

        try {
            //generating qr code.
            BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset),
                    BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
            //converting bitmatrix to bitmap

            int width = matrix.getWidth();
            int height = matrix.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++) {
                    //for black and white
                    //pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
                    //for custom color
                    pixels[offset + x] = matrix.get(x, y) ?
                            ResourcesCompat.getColor(getResources(),R.color.colorB,null) :WHITE;
                }
            }
            //creating bitmap
            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            
           //getting the logo 
            Bitmap overlay = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            //setting bitmap to image view
            imageViewBitmap.setImageBitmap(mergeBitmaps(overlay,bitmap));

        }catch (Exception er){
            Log.e("QrGenerate",er.getMessage());
        }
    }

Combining Qr Code with logo.

Additionally two arguments are passed to this method both are Bitmap’s. In fact the bitmap object is for qr code and overlay is for logo. However don’t mix those. Or we get Qr code inside logo instead of Qr code with logo inside. However Matrix() class is from android.graphics.Matrix; . As a matter of fact it’s a simple process of combining qr code with logo by overlapping one above other.

public Bitmap mergeBitmaps(Bitmap overlay, Bitmap bitmap) {

        int height = bitmap.getHeight();
        int width = bitmap.getWidth();

        Bitmap combined = Bitmap.createBitmap(width, height, bitmap.getConfig());
        Canvas canvas = new Canvas(combined);
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();

        canvas.drawBitmap(bitmap, new Matrix(), null);

        int centreX = (canvasWidth  - overlay.getWidth()) /2;
        int centreY = (canvasHeight - overlay.getHeight()) /2 ;
        canvas.drawBitmap(overlay, centreX, centreY, null);

        return combined;
    }

The entire code.

Instead of click listener button click is specified inside the xml file itself. As a result  length of code is reduced and it’s a good practice. Additionally object smallestDimension is for making square shaped qr code. While it holds the smallest value from width and height. Simultaneously all the methods can produce exceptions, In other word’s  each method need to be enclosed in try and catch.

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ImageView imageViewBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageViewBitmap=(ImageView)findViewById(R.id.imageViewBitmap);
    }
//handling button click
    public void GenerateClick(View view){
        try {
            //setting size of qr code
            int width =300;
            int height = 300;
            int smallestDimension = width < height ? width : height;

            EditText editText=(EditText)findViewById(R.id.editText) ;
            String qrCodeData = editText.getText().toString();
            //setting parameters for qr code
            String charset = "UTF-8"; 
            Map<EncodeHintType, ErrorCorrectionLevel> hintMap =new HashMap<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            CreateQRCode(qrCodeData, charset, hintMap, smallestDimension, smallestDimension);

        } catch (Exception ex) {
            Log.e("QrGenerate",ex.getMessage());
        }
    }

    public  void CreateQRCode(String qrCodeData, String charset, Map hintMap, int qrCodeheight, int qrCodewidth){
       

        try {
            //generating qr code in bitmatrix type
            BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset),
                    BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
            //converting bitmatrix to bitmap

            int width = matrix.getWidth();
            int height = matrix.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++) {
                    //pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
                    pixels[offset + x] = matrix.get(x, y) ?
                            ResourcesCompat.getColor(getResources(),R.color.colorB,null) :WHITE;
                }
            }

            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            //setting bitmap to image view

            Bitmap overlay = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

            imageViewBitmap.setImageBitmap(mergeBitmaps(overlay,bitmap));

        }catch (Exception er){
            Log.e("QrGenerate",er.getMessage());
        }
    }



    public Bitmap mergeBitmaps(Bitmap overlay, Bitmap bitmap) {

        int height = bitmap.getHeight();
        int width = bitmap.getWidth();

        Bitmap combined = Bitmap.createBitmap(width, height, bitmap.getConfig());
        Canvas canvas = new Canvas(combined);
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();

        canvas.drawBitmap(bitmap, new Matrix(), null);

        int centreX = (canvasWidth  - overlay.getWidth()) /2;
        int centreY = (canvasHeight - overlay.getHeight()) /2 ;
        canvas.drawBitmap(overlay, centreX, centreY, null);

        return combined;
    }
}

activity_main.xml

After all the UI contain only basic views EditText, Button, ImageView all inside a LinearLayout with vertical orientation. Though you can see android:onClick="GenerateClick" which is for the method GenerateClick(View view).

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.logicchip.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"/>
        <Button
            android:onClick="GenerateClick"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Generate"/>
        <ImageView
            android:id="@+id/imageViewBitmap"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</RelativeLayout>

 

4 comments on “Create QR Code with Logo in android

Leave a Reply

%d bloggers like this: