diff --git a/README.md b/README.md
index 95a825a..7597c15 100644
--- a/README.md
+++ b/README.md
@@ -19,11 +19,11 @@ Example 1|Example 2|Example 3
| |
-Rounded data dots|Binarized background
------------- | -------------
- |
+Solid dots instead of blocks|Binarized|With logo at the center
+------------ | ------------- | -------------
+ | |
-### Add dependency, 添加依赖项
+### Add dependency into your project, 添加依赖项
Add below lines in build.gradle of your project:
```
@@ -38,37 +38,72 @@ allprojects {
Then, add below lines in build.gradle of your app module:
```
dependencies {
- compile 'com.github.SumiMakito:AwesomeQRCode:1.0.3'
+ compile 'com.github.SumiMakito:AwesomeQRCode:1.0.4'
}
```
### Quick start, 快速上手
```java
-Bitmap qrCode = AwesomeQRCode.create("Makito loves Kafuu Chino.", 800, 20, 0.3f, Color.BLACK, Color.WHITE, backgroundBitmap, true, true);
+Bitmap qrCode = AwesomeQRCode.create("Makito loves Kafuu Chino.", 800, 20);
+Bitmap qrCodeWithBackground = AwesomeQRCode.create("Makito loves Kafuu Chino.", 800, 20, backgroundBitmap);
+Bitmap qrCodeWithLogo = AwesomeQRCode.create("Makito loves Kafuu Chino.", 800, 20, null, logoBitmap);
+Bitmap qrCodeWithBackgroundAndLogo = AwesomeQRCode.create("Makito loves Kafuu Chino.", 800, 20, backgroundBitmap, logoBitmap);
```
### Parameters, 参数
+> Here's a full list of all parameters, but some of them are optional. You can view all the possible simplified methods at the end of AwesomeQRCode.java.
+
+> (Translation) 以下列出全部参数,但其中部分参数是可选的。关于简化的调用方法,请查看 AwesomeQRCode.java 的结尾部分。
+
```java
public static Bitmap create(
- String contents, // Contents to encode. 欲编码的内容
- int size, // Width as well as the height of the output QR code, includes margin. 尺寸, 长宽一致
- int margin, // Margin to add around the QR code. 二维码边缘的外边距
- float dataDotScale, // Scale the data blocks and makes them appear smaller. 数据点缩小比例 (0 < scale < 1.0f)
- int colorDark, // Color of blocks. Will be OVERRIDE by autoColor. (BYTE_DTA, BYTE_POS, BYTE_AGN, BYTE_TMG) 实点的颜色
- int colorLight, // Color of empty space. Will be OVERRIDE by autoColor. (BYTE_EPT) 空白点的颜色
- Bitmap backgroundImage, // The background image to embed in the QR code. If null, no background image will be embedded. 欲嵌入的背景图
- boolean whiteMargin, // If true, background image will not be drawn on the margin area. Default is true. 若为 true, 则背景图将不会绘制到外边距区域
- boolean autoColor, // If true, colorDark will be set to the dominant color of backgroundImage. Default is true. 若为 true, 则将从背景图取主要颜色作为实点颜色
- boolean binarize, // If true, background images will be binarized. Default is false. 若为 true, 背景图像将被二值化处理
- int binarizeThreshold, // Threshold value used while binarizing background images. Default is 128. 0 < threshold < 255. 控制背景图像二值化的阈值
- boolean roundedDataDots // If true, data blocks will appear as filled circles. Default is false. 若为 true, 数据点将以圆形绘制
+ String contents,
+ int size,
+ int margin,
+ float dataDotScale,
+ int colorDark,
+ int colorLight,
+ Bitmap backgroundImage,
+ boolean whiteMargin,
+ boolean autoColor,
+ boolean binarize,
+ int binarizeThreshold,
+ boolean roundedDataDots,
+ Bitmap logoImage,
+ int logoMargin,
+ int logoCornerRadius,
+ float logoScale
) throws IllegalArgumentException { ... }
```
+Parameter | Explanation
+----|----
+contents (String) | Contents to encode. 欲编码的内容
+size (int-px) | Width as well as the height of the output QR code, includes margin. 尺寸, 长宽一致, 包含外边距
+margin (int-px) | Margin to add around the QR code. 二维码图像的外边距, 默认 20px
+dataDotScale (float) | Value used to scale down the data dots' size. (0 < scale < 1.0f) 数据区域点缩小比例
+colorDark (int-color) | Color of "true" blocks. Works only when both colorDark and colorLight are set. (BYTE_DTA, BYTE_POS, BYTE_AGN, BYTE_TMG) 实点的颜色
+colorLight (int-color) | Color of empty space, or "false" blocks. Works only when both colorDark and colorLight are set. (BYTE_EPT) 空白区的颜色
+backgroundImage (Bitmap) | Background image to embed in the QR code. Leave null to disable. 欲嵌入的背景图, 设为 null 以禁用
+whiteMargin (int-px) | If set to true, a white border will appear around the background image. Default is true. 若设为 true, 背景图外将绘制白色边框
+autoColor (boolean) | If set to true, the dominant color of backgroundImage will be used as colorDark. Default is true. 若为 true, 背景图的主要颜色将作为实点的颜色, 即 colorDark
+binarize (boolean) | If set to true, the whole image will be binarized with the given threshold, or default threshold if not specified. Default is false. 若为 true, 背景图像将被二值化处理, 未指定阈值则使用默认值
+binarizeThreshold (int) | Threshold used to binarize the whole image. Default is 128. (0 < threshold < 255) 二值化处理的阈值
+roundedDataDots (boolean) | If set to true, data dots will appear as solid dots instead of blocks. Default is false. 若为 true, 数据点将以圆点绘制, 取代默认的小方块
+logoImage (Bitmap) | Logo image to embed at the center of generated QR code. Leave null to disable. 欲嵌入至二维码中心的 LOGO 标识, 设为 null 以禁用
+logoMargin (int-px) | White margin that appears around the logo image. Leave 0 to disable. LOGO 标识周围的空白边框, 设为 0 以禁用
+logoCornerRadius (int-px) | Radius of the logo's corners. Leave 0 to disable. LOGO 标识及其边框的圆角半径, 设为 0 以禁用
+logoScale (float) | Value used to scale the logo image. Larger value may result in decode failure. Size of the logo equals to `logoScale*(size-2*margin)`. Default is 0.2f. 用于计算 LOGO 大小的值, 过大将导致解码失败, LOGO 尺寸计算公式 `logoScale*(size-2*margin)`, 默认 0.2f
+
+
### Changelog, 更新日志
+#### 1.0.4
+New feature: Embedding a logo image in the QR code.
+Sample/Demo application updated.
+
#### 1.0.3
Added CHARACTER_SET => UTF-8 to QR code's hints before encoding.
Fixed an encoding issue mentioned in [#7](https://github.com/SumiMakito/AwesomeQRCode/issues/7).
diff --git a/app/build.gradle b/app/build.gradle
index 3b08c6c..d0f565a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.github.sumimakito.awesomeqrsample"
minSdkVersion 19
targetSdkVersion 25
- versionCode 7
- versionName "1.6"
+ versionCode 8
+ versionName "1.7"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/src/main/java/com/github/sumimakito/awesomeqrsample/MainActivity.java b/app/src/main/java/com/github/sumimakito/awesomeqrsample/MainActivity.java
index d270663..1856300 100644
--- a/app/src/main/java/com/github/sumimakito/awesomeqrsample/MainActivity.java
+++ b/app/src/main/java/com/github/sumimakito/awesomeqrsample/MainActivity.java
@@ -13,8 +13,9 @@
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
-import android.util.Base64;
+import android.view.KeyEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -28,13 +29,12 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.IOException;
public class MainActivity extends AppCompatActivity {
- private final int SELECT_FILE_REQUEST_CODE = 822;
+ private final int BKG_IMAGE = 822;
+ private final int LOGO_IMAGE = 379;
private ImageView qrCodeImageView;
private EditText etColorLight, etColorDark, etContents, etMargin, etSize;
@@ -53,12 +53,23 @@ public class MainActivity extends AppCompatActivity {
private EditText etBinarizeThreshold;
private Bitmap qrBitmap;
private Button btOpen;
+ private EditText etLogoMargin;
+ private EditText etLogoScale;
+ private EditText etLogoCornerRadius;
+ private Button btRemoveLogoImage;
+ private Button btSelectLogo;
+ private Bitmap logoImage;
+ private ViewGroup configViewContainer, resultViewContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ configViewContainer = (ViewGroup) findViewById(R.id.configViewContainer);
+ resultViewContainer = (ViewGroup) findViewById(R.id.resultViewContainer);
+
+ scrollView = (ScrollView) findViewById(R.id.scrollView);
scrollView = (ScrollView) findViewById(R.id.scrollView);
tvAuthorHint = (TextView) findViewById(R.id.authorHint);
tvJSHint = (TextView) findViewById(R.id.jsHint);
@@ -70,7 +81,9 @@ protected void onCreate(Bundle savedInstanceState) {
etMargin = (EditText) findViewById(R.id.margin);
etDotScale = (EditText) findViewById(R.id.dotScale);
btSelectBG = (Button) findViewById(R.id.backgroundImage);
+ btSelectLogo = (Button) findViewById(R.id.logoImage);
btRemoveBackgroundImage = (Button) findViewById(R.id.removeBackgroundImage);
+ btRemoveLogoImage = (Button) findViewById(R.id.removeLogoImage);
btGenerate = (Button) findViewById(R.id.generate);
btOpen = (Button) findViewById(R.id.open);
ckbWhiteMargin = (CheckBox) findViewById(R.id.whiteMargin);
@@ -78,6 +91,10 @@ protected void onCreate(Bundle savedInstanceState) {
ckbBinarize = (CheckBox) findViewById(R.id.binarize);
ckbRoundedDataDots = (CheckBox) findViewById(R.id.rounded);
etBinarizeThreshold = (EditText) findViewById(R.id.binarizeThreshold);
+ etLogoMargin = (EditText) findViewById(R.id.logoMargin);
+ etLogoScale = (EditText) findViewById(R.id.logoScale);
+ etLogoCornerRadius = (EditText) findViewById(R.id.logoRadius);
+ etBinarizeThreshold = (EditText) findViewById(R.id.binarizeThreshold);
ckbAutoColor.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
@@ -100,7 +117,17 @@ public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
- startActivityForResult(intent, SELECT_FILE_REQUEST_CODE);
+ startActivityForResult(intent, BKG_IMAGE);
+ }
+ });
+
+ btSelectLogo.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("image/*");
+ startActivityForResult(intent, LOGO_IMAGE);
}
});
@@ -119,6 +146,14 @@ public void onClick(View v) {
}
});
+ btRemoveLogoImage.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ logoImage = null;
+ Toast.makeText(MainActivity.this, "Logo image removed.", Toast.LENGTH_SHORT).show();
+ }
+ });
+
btGenerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -134,7 +169,11 @@ public void onClick(View v) {
ckbAutoColor.isChecked(),
ckbBinarize.isChecked(),
etBinarizeThreshold.getText().length() == 0 ? 128 : Integer.parseInt(etBinarizeThreshold.getText().toString()),
- ckbRoundedDataDots.isChecked()
+ ckbRoundedDataDots.isChecked(),
+ logoImage,
+ etLogoMargin.getText().length() == 0 ? 10 : Integer.parseInt(etLogoMargin.getText().toString()),
+ etLogoCornerRadius.getText().length() == 0 ? 8 : Integer.parseInt(etLogoCornerRadius.getText().toString()),
+ etLogoScale.getText().length() == 0 ? 10 : Float.parseFloat(etLogoScale.getText().toString())
);
} catch (Exception e) {
Toast.makeText(MainActivity.this, "Error occurred, please check your configs.", Toast.LENGTH_LONG).show();
@@ -190,14 +229,23 @@ private void acquireStoragePermissions() {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == SELECT_FILE_REQUEST_CODE && resultCode == RESULT_OK && data.getData() != null) {
+ if (resultCode == RESULT_OK && data.getData() != null) {
try {
Uri imageUri = data.getData();
- backgroundImage = BitmapFactory.decodeFile(ContentHelper.absolutePathFromUri(this, imageUri));
- Toast.makeText(this, "Background image added.", Toast.LENGTH_SHORT).show();
+ if (requestCode == BKG_IMAGE) {
+ backgroundImage = BitmapFactory.decodeFile(ContentHelper.absolutePathFromUri(this, imageUri));
+ Toast.makeText(this, "Background image added.", Toast.LENGTH_SHORT).show();
+ } else if (requestCode == LOGO_IMAGE) {
+ logoImage = BitmapFactory.decodeFile(ContentHelper.absolutePathFromUri(this, imageUri));
+ Toast.makeText(this, "Logo image added.", Toast.LENGTH_SHORT).show();
+ }
} catch (Exception e) {
e.printStackTrace();
- Toast.makeText(this, "Failed to add the background image.", Toast.LENGTH_SHORT).show();
+ if (requestCode == BKG_IMAGE) {
+ Toast.makeText(this, "Failed to add the background image.", Toast.LENGTH_SHORT).show();
+ } else if (requestCode == LOGO_IMAGE) {
+ Toast.makeText(this, "Failed to add the logo image.", Toast.LENGTH_SHORT).show();
+ }
}
}
super.onActivityResult(requestCode, resultCode, data);
@@ -205,7 +253,8 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
private void generate(final String contents, final int size, final int margin, final float dotScale,
final int colorDark, final int colorLight, final Bitmap background, final boolean whiteMargin,
- final boolean autoColor, final boolean binarize, final int binarizeThreshold, final boolean roundedDD) {
+ final boolean autoColor, final boolean binarize, final int binarizeThreshold, final boolean roundedDD,
+ final Bitmap logoImage, final int logoMargin, final int logoCornerRadius, final float logoScale) {
if (generating) return;
generating = true;
progressDialog = new ProgressDialog.Builder(this).setMessage("Generating...").setCancelable(false).create();
@@ -216,17 +265,13 @@ public void run() {
try {
qrBitmap = AwesomeQRCode.create(contents, size, margin, dotScale, colorDark,
colorLight, background, whiteMargin, autoColor, binarize, binarizeThreshold,
- roundedDD);
+ roundedDD, logoImage, logoMargin, logoCornerRadius, logoScale);
runOnUiThread(new Runnable() {
@Override
public void run() {
qrCodeImageView.setImageBitmap(qrBitmap);
- scrollView.post(new Runnable() {
- @Override
- public void run() {
- scrollView.fullScroll(View.FOCUS_DOWN);
- }
- });
+ configViewContainer.setVisibility(View.GONE);
+ resultViewContainer.setVisibility(View.VISIBLE);
if (progressDialog != null) progressDialog.dismiss();
generating = false;
}
@@ -237,6 +282,8 @@ public void run() {
@Override
public void run() {
if (progressDialog != null) progressDialog.dismiss();
+ configViewContainer.setVisibility(View.VISIBLE);
+ resultViewContainer.setVisibility(View.GONE);
generating = false;
}
});
@@ -271,4 +318,16 @@ public static File getPublicContainer() {
aqr.mkdirs();
return aqr;
}
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (configViewContainer.getVisibility() != View.VISIBLE) {
+ configViewContainer.setVisibility(View.VISIBLE);
+ resultViewContainer.setVisibility(View.GONE);
+ return true;
+ }
+ }
+ return super.onKeyDown(keyCode, event);
+ }
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 049fcab..51edac5 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -8,270 +8,405 @@
android:orientation="vertical"
tools:context="com.github.sumimakito.awesomeqrsample.MainActivity">
-
+
+
+ android:layout_below="@+id/authorHint"
+ android:orientation="vertical"
+ android:visibility="visible">
-
+ android:layout_height="match_parent"
+ android:layout_above="@+id/generate"
+ android:clipToPadding="false"
+ android:fadingEdge="vertical"
+ android:fillViewport="true">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:gravity="top|center_horizontal"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
diff --git a/art/awesome-qr-6.png b/art/awesome-qr-6.png
new file mode 100644
index 0000000..e3fc099
Binary files /dev/null and b/art/awesome-qr-6.png differ
diff --git a/library/build.gradle b/library/build.gradle
index 2ec0625..013aef6 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -6,8 +6,8 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 25
- versionCode 4
- versionName "1.0.3"
+ versionCode 5
+ versionName "1.0.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
diff --git a/library/src/main/java/com/github/sumimakito/awesomeqr/AwesomeQRCode.java b/library/src/main/java/com/github/sumimakito/awesomeqr/AwesomeQRCode.java
index 6effe60..4ab6dae 100644
--- a/library/src/main/java/com/github/sumimakito/awesomeqr/AwesomeQRCode.java
+++ b/library/src/main/java/com/github/sumimakito/awesomeqr/AwesomeQRCode.java
@@ -5,6 +5,10 @@
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.Log;
import com.google.zxing.EncodeHintType;
@@ -36,53 +40,12 @@ public class AwesomeQRCode {
private static final int BYTE_PTC = 0x5;
private static float DEFAULT_DTA_DOT_SCALE = 0.3f;
+ private static float DEFAULT_LOGO_SCALE = 0.2f;
+ private static int DEFAULT_MARGIN = 20;
+ private static int DEFAULT_LOGO_MARGIN = 10;
+ private static int DEFAULT_LOGO_RADIUS = 8;
private static int DEFAULT_BINARIZING_THRESHOLD = 128;
- public static Bitmap create(String contents, int size, int margin, int colorDark, int colorLight) throws IllegalArgumentException {
- return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, null, true, true);
- }
-
- public static Bitmap create(String contents, int size, int margin, int colorDark, int colorLight,
- Bitmap backgroundImage) throws IllegalArgumentException {
- return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage, true, true);
- }
-
- public static Bitmap create(String contents, int size, int margin, int colorDark, int colorLight,
- Bitmap backgroundImage, boolean whiteMargin) throws IllegalArgumentException {
- return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage, whiteMargin, true);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark, int colorLight,
- Bitmap backgroundImage, boolean whiteMargin) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage, whiteMargin, false);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, Bitmap backgroundImage,
- boolean whiteMargin, boolean binarize) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, Color.BLACK, Color.WHITE, backgroundImage, whiteMargin, true, binarize, DEFAULT_BINARIZING_THRESHOLD, false);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, Bitmap backgroundImage,
- boolean whiteMargin, boolean binarize, boolean roundedDataDots) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, Color.BLACK, Color.WHITE, backgroundImage, whiteMargin, true, binarize, DEFAULT_BINARIZING_THRESHOLD, roundedDataDots);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, Bitmap backgroundImage,
- boolean whiteMargin, boolean binarize, int binarizeThreshold) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, Color.BLACK, Color.WHITE, backgroundImage, whiteMargin, true, binarize, binarizeThreshold, false);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
- int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage, whiteMargin, autoColor, false);
- }
-
- public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
- int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor,
- boolean binarize) throws IllegalArgumentException {
- return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage, whiteMargin, autoColor, binarize, DEFAULT_BINARIZING_THRESHOLD, false);
- }
-
/**
* Create a QR matrix and render it use given configs.
*
@@ -95,15 +58,20 @@ public static Bitmap create(String contents, int size, int margin, float dataDot
* @param backgroundImage The background image to embed in the QR code. If null, no background image will be embedded.
* @param whiteMargin If true, background image will not be drawn on the margin area.
* @param autoColor If true, colorDark will be set to the dominant color of backgroundImage.
- * @param binarize If true, background images will be binarized. Default is false.
- * @param binarizeThreshold Threshold value used while binarizing background images. Default is 128. 0 < threshold < 255.
+ * @param binarize If true, all images will be binarized while rendering. Default is false.
+ * @param binarizeThreshold Threshold value used while binarizing. Default is 128. 0 < threshold < 255.
* @param roundedDataDots If true, data blocks will appear as filled circles. Default is false.
+ * @param logoImage The logo image which appears at the center of the QR code. Null to disable.
+ * @param logoMargin The margin around the logo image. 0 to disable.
+ * @param logoCornerRadius The radius of logo image's corners. 0 to disable.
+ * @param logoScale Logo's size = logoScale * innerRenderSize
* @return Bitmap of QR code
* @throws IllegalArgumentException Refer to the messages below.
*/
public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor,
- boolean binarize, int binarizeThreshold, boolean roundedDataDots) throws IllegalArgumentException {
+ boolean binarize, int binarizeThreshold, boolean roundedDataDots,
+ Bitmap logoImage, int logoMargin, int logoCornerRadius, float logoScale) throws IllegalArgumentException {
if (contents.isEmpty()) {
throw new IllegalArgumentException("Error: contents is empty. (contents.isEmpty())");
}
@@ -123,12 +91,15 @@ public static Bitmap create(String contents, int size, int margin, float dataDot
if (dataDotScale < 0 || dataDotScale > 1) {
throw new IllegalArgumentException("Error: an illegal data dot scale is given. (dataDotScale < 0 || dataDotScale > 1)");
}
- return render(byteMatrix, size - 2 * margin, margin, dataDotScale, colorDark, colorLight, backgroundImage, whiteMargin, autoColor, binarize, binarizeThreshold, roundedDataDots);
+ return render(byteMatrix, size - 2 * margin, margin, dataDotScale, colorDark, colorLight, backgroundImage,
+ whiteMargin, autoColor, binarize, binarizeThreshold, roundedDataDots, logoImage, logoMargin,
+ logoCornerRadius, logoScale);
}
private static Bitmap render(ByteMatrix byteMatrix, int innerRenderedSize, int margin, float dataDotScale,
int colorDark, int colorLight, Bitmap backgroundImage, boolean whiteMargin,
- boolean autoColor, boolean binarize, int binarizeThreshold, boolean roundedDataDots) {
+ boolean autoColor, boolean binarize, int binarizeThreshold, boolean roundedDataDots,
+ Bitmap logoImage, int logoMargin, int logoCornerRadius, float logoScale) {
int nCount = byteMatrix.getWidth();
float nWidth = (float) innerRenderedSize / nCount;
float nHeight = (float) innerRenderedSize / nCount;
@@ -147,17 +118,19 @@ private static Bitmap render(ByteMatrix byteMatrix, int innerRenderedSize, int m
colorDark = getDominantColor(backgroundImage);
}
- if (binarize && backgroundImage != null) {
- int threshold = DEFAULT_BINARIZING_THRESHOLD;
+ int binThreshold = DEFAULT_BINARIZING_THRESHOLD;
+ if (binarize) {
if (binarizeThreshold > 0 && binarizeThreshold < 255) {
- threshold = binarizeThreshold;
+ binThreshold = binarizeThreshold;
}
colorDark = Color.BLACK;
colorLight = Color.WHITE;
- binarize(backgroundImageScaled, threshold);
+ if (backgroundImage != null)
+ binarize(backgroundImageScaled, binThreshold);
}
Paint paint = new Paint();
+ paint.setAntiAlias(true);
Paint paintDark = new Paint();
paintDark.setColor(colorDark);
paintDark.setAntiAlias(true);
@@ -239,6 +212,44 @@ private static Bitmap render(ByteMatrix byteMatrix, int innerRenderedSize, int m
}
}
+ if (logoImage != null) {
+ if (logoScale <= 0 || logoScale >= 1) {
+ logoScale = DEFAULT_LOGO_SCALE;
+ }
+ if (logoMargin < 0 || logoMargin * 2 >= innerRenderedSize) {
+ logoMargin = DEFAULT_LOGO_MARGIN;
+ }
+ int logoScaledSize = (int) (innerRenderedSize * logoScale);
+
+ if (logoCornerRadius < 0) logoCornerRadius = 0;
+ if (logoCornerRadius * 2 > logoScaledSize)
+ logoCornerRadius = (int) (logoScaledSize * 0.5);
+
+ Bitmap logoScaled = Bitmap.createScaledBitmap(logoImage, logoScaledSize, logoScaledSize, true);
+ Bitmap logoOpt = Bitmap.createBitmap(logoScaled.getWidth(), logoScaled.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas logoCanvas = new Canvas(logoOpt);
+ final Rect logoRect = new Rect(0, 0, logoScaled.getWidth(), logoScaled.getHeight());
+ final RectF logoRectF = new RectF(logoRect);
+ Paint logoPaint = new Paint();
+ logoPaint.setAntiAlias(true);
+ logoPaint.setColor(0xFFFFFFFF);
+ logoPaint.setStyle(Paint.Style.FILL);
+ logoCanvas.drawARGB(0, 0, 0, 0);
+ logoCanvas.drawRoundRect(logoRectF, logoCornerRadius, logoCornerRadius, logoPaint);
+ logoPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ logoCanvas.drawBitmap(logoScaled, logoRect, logoRect, logoPaint);
+ logoPaint.setColor(colorLight);
+ logoPaint.setStyle(Paint.Style.STROKE);
+ logoPaint.setStrokeWidth(logoMargin);
+ logoCanvas.drawRoundRect(logoRectF, logoCornerRadius, logoCornerRadius, logoPaint);
+
+ if (binarize)
+ binarize(logoOpt, binThreshold);
+
+ canvas.drawBitmap(logoOpt, (int) (0.5 * (renderedBitmap.getWidth() - logoOpt.getWidth())),
+ (int) (0.5 * (renderedBitmap.getHeight() - logoOpt.getHeight())), paint);
+ }
+
return renderedBitmap;
}
@@ -384,5 +395,83 @@ private static void binarize(Bitmap bitmap, int threshold) {
}
}
}
+
+ /* TONS OF SHORTENED METHODS */
+
+ public static Bitmap create(String contents, int size, int margin) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, 0, 0, null, true, true, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, int colorDark, int colorLight) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, null, true, false, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, Bitmap backgroundImage) throws IllegalArgumentException {
+ return create(contents, size, DEFAULT_MARGIN, DEFAULT_DTA_DOT_SCALE, 0, 0, backgroundImage, true, true, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, Bitmap backgroundImage, Bitmap logoImage) throws IllegalArgumentException {
+ return create(contents, size, DEFAULT_MARGIN, DEFAULT_DTA_DOT_SCALE, 0, 0, backgroundImage, true, true, false, 0, false, logoImage, DEFAULT_LOGO_MARGIN, DEFAULT_LOGO_RADIUS, DEFAULT_LOGO_SCALE);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, int colorDark,
+ int colorLight, Bitmap backgroundImage) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage,
+ true, false, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int colorDark,
+ int colorLight, Bitmap backgroundImage, Bitmap logoImage) throws IllegalArgumentException {
+ return create(contents, size, DEFAULT_MARGIN, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage, true, false, false, 0,
+ false, logoImage, DEFAULT_LOGO_MARGIN, DEFAULT_LOGO_RADIUS, DEFAULT_LOGO_SCALE);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, int colorDark,
+ int colorLight, Bitmap backgroundImage, Bitmap logoImage) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage, true, false, false, 0,
+ false, logoImage, DEFAULT_LOGO_MARGIN, DEFAULT_LOGO_RADIUS, DEFAULT_LOGO_SCALE);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, Bitmap backgroundImage) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, 0, 0, backgroundImage,
+ true, true, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, Bitmap backgroundImage, boolean whiteMargin) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, 0, 0, backgroundImage,
+ whiteMargin, true, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, Bitmap backgroundImage, boolean whiteMargin, boolean roundedDataDots) throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, 0, 0, backgroundImage,
+ whiteMargin, true, false, 0, roundedDataDots, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, int colorDark, int colorLight, Bitmap backgroundImage, boolean whiteMargin)
+ throws IllegalArgumentException {
+ return create(contents, size, margin, DEFAULT_DTA_DOT_SCALE, colorDark, colorLight, backgroundImage,
+ whiteMargin, false, false, 0, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
+ int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor,
+ boolean roundedDataDots) throws IllegalArgumentException {
+ return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage,
+ whiteMargin, autoColor, false, 0, roundedDataDots, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
+ int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor,
+ boolean binarize, int binarizeThreshold) throws IllegalArgumentException {
+ return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage,
+ whiteMargin, autoColor, binarize, binarizeThreshold, false, null, 0, 0, 0);
+ }
+
+ public static Bitmap create(String contents, int size, int margin, float dataDotScale, int colorDark,
+ int colorLight, Bitmap backgroundImage, boolean whiteMargin, boolean autoColor,
+ boolean binarize, int binarizeThreshold, boolean roundedDataDots) throws IllegalArgumentException {
+ return create(contents, size, margin, dataDotScale, colorDark, colorLight, backgroundImage,
+ whiteMargin, autoColor, binarize, binarizeThreshold, roundedDataDots, null, 0, 0, 0);
+ }
}