Skip to content

Commit

Permalink
Merge pull request #11 from SumiMakito/develop
Browse files Browse the repository at this point in the history
V1.0.4 released
  • Loading branch information
sumimakito authored May 7, 2017
2 parents cd5e6a1 + bfe5df5 commit a64a50f
Show file tree
Hide file tree
Showing 7 changed files with 664 additions and 346 deletions.
71 changes: 53 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Example 1|Example 2|Example 3
<img src="art/awesome-qr-1.png" width="400"> | <img src="art/awesome-qr-2.png" width="400"> | <img src="art/awesome-qr-3.png" width="400">


Rounded data dots|Binarized background
------------ | -------------
<img src="art/awesome-qr-4.png" width="400"> | <img src="art/awesome-qr-5.png" width="400">
Solid dots instead of blocks|Binarized|With logo at the center
------------ | ------------- | -------------
<img src="art/awesome-qr-4.png" width="400"> | <img src="art/awesome-qr-5.png" width="400"> | <img src="art/awesome-qr-6.png" width="400">

### Add dependency, 添加依赖项
### Add dependency into your project, 添加依赖项

Add below lines in build.gradle of your project:
```
Expand All @@ -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).
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -70,14 +81,20 @@ 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);
ckbAutoColor = (CheckBox) findViewById(R.id.autoColor);
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
Expand All @@ -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);
}
});

Expand All @@ -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) {
Expand All @@ -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();
Expand Down Expand Up @@ -190,22 +229,32 @@ 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);
}

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();
Expand All @@ -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;
}
Expand All @@ -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;
}
});
Expand Down Expand Up @@ -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);
}
}
Loading

0 comments on commit a64a50f

Please sign in to comment.