条形码、二维码的生成与扫描、解析本地二维码

Github项目解析(十)–>几行代码快速集成二维码扫描库 - CSDN博客 http://blog.csdn.net/qq_23547831/article/details/52037710

自行添加了条形码的生成功能,图片路径获取代码。
效果图:
这里写图片描述这里写图片描述

**

准备工作

**:
1.添加权限

<!-- 对存储设备的读写权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 相机 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- 振动 -->
    <uses-permission android:name="android.permission.VIBRATE" />

2.添加依赖:

compile 'cn.yipianfengye.android:zxing-library:2.2'

准备就绪了,马上开干啦。最开始解析本地含二维码的图片时,获取图片路径总报错,我就把它单独放出来进行测试了,现在当然是没问题啦~
所以首界面的功能就是:二维码的扫描、生成(有无logo)、条形码的生成,解析图片界面的功能就只是解析本地包含二维码的图片而已。说了这么多的废话了,是时候亮家伙了
**

功能

**

1.首页布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_parse_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_gravity="bottom"
        android:layout_marginTop="15dp"
        android:textColor="@color/colorAccent"
        android:text="解析二维码图片"/>
    <TextView
        android:id="@+id/tv_scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_marginTop="15dp"
        android:text="扫描二维码"/>

    <TextView
        android:id="@+id/tv_parse_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:layout_marginTop="15dp"
        android:paddingLeft="5dp"
        android:text="扫描解析结果:"/>
    <EditText
        android:id="@+id/ed_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:hint="请输入"/>
    <TextView
        android:id="@+id/tv_make_code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_marginTop="15dp"
        android:text="生成有logo的二维码"/>
    <TextView
        android:id="@+id/tv_make_code_no_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_marginTop="15dp"
        android:text="生成无logo的二维码"/>
    <TextView
        android:id="@+id/tv_make_bar_code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_marginTop="15dp"
        android:text="生成条形码"/>
    <ImageView
        android:id="@+id/img_code"
        android:layout_marginTop="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

2.activity代码

我喜欢写很多注释,这样方便自己复习功能时,直接看代码就可以看到很多相关的知识点,但也许这篇的注释并不多,因为不需要啊。
注意,需要先执行初始化操作ZXingLibrary.initDisplayOpinion(this);


/**
 * 扫描二维码
 * 解析图片二维码
 * 根据输入的文字生成有无logo的二维码
 * 根据输入的文字生成条形码
 */
public class HomeActivity extends AppCompatActivity {

    private TextView tvScan;
    private TextView tvParseResult;
    private TextView tvMakeCode;
    private TextView tvMakeCodeNoLogo;
    private TextView tvMakeBarCode;
    private EditText edInput;
    private ImageView imgCode;
    private Bitmap mBitmap;
    private TextView tvParseImage;

    private static final int REQUEST_CODE = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        //初始化
        ZXingLibrary.initDisplayOpinion(this);

        tvScan = (TextView) this.findViewById(R.id.tv_scan);
        tvParseResult  =  (TextView) this.findViewById(R.id.tv_parse_result);
        edInput = (EditText) this.findViewById(R.id.ed_input);
        tvMakeCode = (TextView) this.findViewById(R.id.tv_make_code);
        tvMakeCodeNoLogo = (TextView) this.findViewById(R.id.tv_make_code_no_logo);
        tvMakeBarCode = (TextView) this.findViewById(R.id.tv_make_bar_code);
        imgCode = (ImageView) this.findViewById(R.id.img_code);
        tvParseImage =  (TextView) this.findViewById(R.id.tv_parse_image);

        //解析二维码图片
        tvParseImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(HomeActivity.this,ActParseImage.class);
                startActivity(intent);
            }
        });

        //扫描二维码
        tvScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(HomeActivity.this, CaptureActivity.class);
                startActivityForResult(intent, REQUEST_CODE);
            }
        });

        //生成有logo的二维码图片
        tvMakeCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String textContent = edInput.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
                imgCode.setImageBitmap(mBitmap);
            }
        });
        //生成无logo的二维码图片
        tvMakeCodeNoLogo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String textContent = edInput.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
                imgCode.setImageBitmap(mBitmap);
            }
        });
        tvMakeBarCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String textContent = edInput.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(HomeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                makeBarCode(textContent);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode){
            case REQUEST_CODE:
                //处理扫描结果(在界面上显示)
                if (null != data) {
                    Bundle bundle = data.getExtras();
                    if (bundle == null) {
                        return;
                    }
                    if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                        String result = bundle.getString(CodeUtils.RESULT_STRING);
                        tvParseResult.setText("扫描解析结果:" + result);
                    } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                        Toast.makeText(HomeActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }

    /**
     * 制作条形码
     */
    public void makeBarCode(String barCode){
        int size = barCode.length();
        for (int i = 0; i < size; i++) {
            int c = barCode.charAt(i);
            if ((19968 <= c && c < 40623)) {
                Toast.makeText(HomeActivity.this, "生成条形码的时刻不能是中文", Toast.LENGTH_SHORT).show();
                return;
            }
        }
        Bitmap bmp = null;
        try {
            if (!TextUtils.isEmpty(barCode)) {
                bmp = CreateOneDCode(barCode);
            }
        } catch (WriterException e) {
            e.printStackTrace();
        }
        if (bmp != null) {
            imgCode.setImageBitmap(bmp);
        }
    }

    /**
     * 用于将给定的内容生成成一维条码 注:目前生成内容为中文的话将直接报错,要修改底层jar包的内容
     *
     * @param content 将要生成一维条码的内容
     * @return 返回生成好的一维条码bitmap
     * @throws WriterException WriterException异常
     */
    public Bitmap CreateOneDCode(String content) throws WriterException {
        // 生成一维条码,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
        int imgWidth = this.getResources().getDisplayMetrics().widthPixels - 40;
        int imgHeight = imgWidth / 5 * 2;

        BitMatrix matrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.CODE_128, imgWidth, imgHeight);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (matrix.get(x, y)) {
                    pixels[y * width + x] = 0xff000000;
                }
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        // 通过像素数组生成bitmap,具体参考api
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }
}

3.解析二维码图片布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_parse_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        android:layout_marginTop="15dp"
        android:text="解析二维码图片"/>
    <TextView
        android:id="@+id/tv_parse_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:layout_marginTop="15dp"
        android:paddingLeft="5dp"
        android:text="解析结果:"/>
    <ImageView
        android:id="@+id/img_code"
        android:layout_marginTop="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

4.解析二维码图片activity

注意哦,Android6.0及以上不仅要声明权限,还需要在使用的时候,自动询问,此处读取本地图片是必须要进行这样的操作的,但我在这偷了个懒,我没有写自动询问权限,直接去设置里面全部授予了

public class ActParseImage extends AppCompatActivity{

    private TextView tvParseImage;
    private TextView tvParseResult;
    private ImageView imgCode;

    private static final int REQUEST_IMAGE = 1102;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_parseimage);

        //初始化
        ZXingLibrary.initDisplayOpinion(this);

        tvParseImage =  (TextView) this.findViewById(R.id.tv_parse_image);
        tvParseResult  =  (TextView) this.findViewById(R.id.tv_parse_result);
        imgCode = (ImageView) this.findViewById(R.id.img_code);

        //解析二维码图片
        tvParseImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tvParseResult.setText("");
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/*");
                startActivityForResult(intent, REQUEST_IMAGE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode){
            case REQUEST_IMAGE:
                if (data != null) {
                    String imagePath = "";//获得图片路径
                    Uri uri = data.getData();
                    imagePath = getRealPathFromUri(this,uri);
                    try {
                        CodeUtils.analyzeBitmap(imagePath, new CodeUtils.AnalyzeCallback() {
                            @Override
                            public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
                                tvParseResult.setText("解析结果:" + result);
                                imgCode.setImageBitmap(mBitmap);
                            }

                            @Override
                            public void onAnalyzeFailed() {
                                Toast.makeText(ActParseImage.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
    }

    /**
     * 根据Uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    public static String getRealPathFromUri(Context context, Uri uri) {
        int sdkVersion = Build.VERSION.SDK_INT;
        if (sdkVersion >= 19) { // api >= 19
            return getRealPathFromUriAboveApi19(context, uri);
        } else { // api < 19
            return getRealPathFromUriBelowAPI19(context, uri);
        }
    }

    /**
     * 适配api19以下(不包括api19),根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
        return getDataColumn(context, uri, null, null);
    }

    /**
     * 适配api19及以上,根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    @SuppressLint("NewApi")
    private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
        String filePath = null;
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是document类型的 uri, 则通过document id来进行处理
            String documentId = DocumentsContract.getDocumentId(uri);
            if (isMediaDocument(uri)) { // MediaProvider
                // 使用':'分割
                String id = documentId.split(":")[1];

                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = {id};
                filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
            } else if (isDownloadsDocument(uri)) { // DownloadsProvider
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
                filePath = getDataColumn(context, contentUri, null, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())){
            // 如果是 content 类型的 Uri
            filePath = getDataColumn(context, uri, null, null);
        } else if ("file".equals(uri.getScheme())) {
            // 如果是 file 类型的 Uri,直接获取图片对应的路径
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
     * @return
     */
    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        String path = null;

        String[] projection = new String[]{MediaStore.Images.Media.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                path = cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            if (cursor != null) {
                cursor.close();
            }
        }
        return path;
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is MediaProvider
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is DownloadsProvider
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值