生成二維碼、識別二維碼

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private Button btn_create,btn_scanner;
    private ImageView imageView;
    private EditText et;
    private String time;
    private File file null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_create = (Button) findViewById(R.id.btn_create);
        btn_scanner = (Button) findViewById(R.id.btn_scanner);
        imageView = (ImageView) findViewById(R.id.image);
        et = (EditText) findViewById(R.id.editText);



        btn_create.setOnClickListener(this);
        btn_scanner.setOnClickListener(this);
        imageView.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                saveCurrentImage();
                return true;
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_create:
                String msg = et.getText().toString();
                if(TextUtils.isEmpty(msg)){
                    Toast.makeText(MainActivity.this"請輸入信息", Toast.LENGTH_LONG).show();
                    return;
                }
                //生成二維碼圖片,第一個參數是二維碼的內容,第二個參數是正方形圖片的邊長,單位是像素
                Bitmap bitmap = null;
                try {
                    bitmap = BitmapUtil.createQRCode(msg, 400);
                } catch (WriterException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                imageView.setImageBitmap(bitmap);
                break;

            case R.id.btn_scanner:
               /* Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivity(intent);*/
                break;

            default:
                break;
        }
    }

    //這種方法狀態欄是空白,顯示不了狀態欄的信息
    private void saveCurrentImage()
    {
        //獲取當前屏幕的大小
        int width = getWindow().getDecorView().getRootView().getWidth();
        int height = getWindow().getDecorView().getRootView().getHeight();
        //生成相同大小的圖片
        Bitmap temBitmap = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888 );
        //找到當前頁面的根佈局
        View view =  getWindow().getDecorView().getRootView();
        //設置緩存
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        //從緩存中獲取當前屏幕的圖片,創建一個DrawingCache的拷貝,因爲DrawingCache得到的位圖在禁用後會被回收
        temBitmap = view.getDrawingCache();
        SimpleDateFormat df = new SimpleDateFormat("yyyymmddhhmmss");
        time = df.format(new Date());
        if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
            file new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/screen",time ".png");
            if(!file.exists()){
                file.getParentFile().mkdirs();
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
                temBitmap.compress(Bitmap.CompressFormat.PNG100, fos);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/screen/" time ".png";
                    final Result result = parseQRcodeBitmap(path);
                    file.delete();
                    runOnUiThread(new Runnable() {
                        public void run() {
                           // Toast.makeText(MainActivity.this, result.toString(), Toast.LENGTH_LONG).show();
                            Intent intent = new Intent();
                            intent.setAction("android.intent.action.VIEW");
                            Uri content_url = Uri.parse(result.toString());
                            intent.setData(content_url);
                            startActivity(intent);
                        }
                    });
                }
            }).start();
            //禁用DrawingCahce否則會影響性能 ,而且不禁止會導致每次截圖到保存的是第一次截圖緩存的位圖
            view.setDrawingCacheEnabled(false);
        }
    }

    //解析二維碼圖片,返回結果封裝在Result對象中
    private Result  parseQRcodeBitmap(String bitmapPath){
        //解析轉換類型UTF-8
        Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET"utf-8");
        //獲取到待解析的圖片
        BitmapFactory.Options options = new BitmapFactory.Options();
        //如果我們把inJustDecodeBounds設爲true,那麼BitmapFactory.decodeFile(String path, Options opt)
        //並不會真的返回一個Bitmap給你,它僅僅會把它的寬,高取回來給你
        options.inJustDecodeBounds true;
        //此時的bitmap是null,這段代碼之後,options.outWidth 和 options.outHeight就是我們想要的寬和高了
        Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath,options);
        //我們現在想取出來的圖片的邊長(二維碼圖片是正方形的)設置爲400像素
        //以上這種做法,雖然把bitmap限定到了我們要的大小,但是並沒有節約內存,如果要節約內存,我們還需要使用inSimpleSize這個屬性
        options.inSampleSize = options.outHeight 400;
        if(options.inSampleSize <= 0){
            options.inSampleSize 1//防止其值小於或等於0
        }
        /**
         * 輔助節約內存設置
         *
         * options.inPreferredConfig = Bitmap.Config.ARGB_4444;    // 默認是Bitmap.Config.ARGB_8888
         * options.inPurgeable = true;
         * options.inInputShareable = true;
         */
        options.inJustDecodeBounds false;
        bitmap = BitmapFactory.decodeFile(bitmapPath, options);
        //新建一個RGBLuminanceSource對象,將bitmap圖片傳給此對象
        RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap);
        //將圖片轉換成二進制圖片
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
        //初始化解析對象
        QRCodeReader reader = new QRCodeReader();
        //開始解析
        Result result = null;
        try {
            result = reader.decode(binaryBitmap, hints);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return result;
    }
}




public class BitmapUtil {
    /**
     * 生成一個二維碼圖像
     *
     * @param url
     *            傳入的字符串,通常是一個URL
     * @param QR_WIDTH
     *            寬度(像素值px)
     * @param QR_HEIGHT
     *            高度(像素值px)
     * @return
     */
    public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH,
                                                   int QR_HEIGHT) {
        try {
            // 判斷URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return null;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET"UTF-8");
            // 圖像數據轉換,使用了矩陣轉換
            BitMatrix bitMatrix = new QRCodeWriter().encode(url,
                    BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
            int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
            // 下面這裏按照二維碼的算法,逐個生成二維碼的圖片,
            // 兩個for循環是圖片橫列掃描的結果
            for (int y = 0; y < QR_HEIGHT; y++) {
                for (int x = 0; x < QR_WIDTH; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * QR_WIDTH + x] = 0xff000000;
                    } else {
                        pixels[y * QR_WIDTH + x] = 0xffffffff;
                    }
                }
            }
            // 生成二維碼圖片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,
                    Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, QR_WIDTH, 00, QR_WIDTH, QR_HEIGHT);
            // 顯示到一個ImageView上面
            // sweepIV.setImageBitmap(bitmap);
            return bitmap;
        } catch (WriterException e) {
            Log.i("log""生成二維碼錯誤" + e.getMessage());
            return null;
        }
    }

    private static final int BLACK 0xff000000;

    /**
     * 生成一個二維碼圖像
     *
     * @param url
     *            傳入的字符串,通常是一個URL
     * @param widthAndHeight
     *           圖像的寬高
     * @return
     */
    public static Bitmap createQRCode(String str, int widthAndHeight)
            throws WriterException {
        Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
        hints.put(EncodeHintType.CHARACTER_SET"utf-8");
        try {
            str = new String(str.getBytes("UTF-8"), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        BitMatrix matrix = new MultiFormatWriter().encode(str,
                BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
        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] = BLACK;
                }
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 00, width, height);
        return bitmap;
    }
}





public class RGBLuminanceSource  extends LuminanceSource {

    private byte bitmapPixels[];

    protected RGBLuminanceSource(Bitmap bitmap) {
        super(bitmap.getWidth(), bitmap.getHeight());

        // 首先,要取得該圖片的像素數組內容
        int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
        this.bitmapPixels new byte[bitmap.getWidth() * bitmap.getHeight()];
        bitmap.getPixels(data, 0, getWidth(), 00, getWidth(), getHeight());

        // 將int數組轉換爲byte數組,也就是取像素值中藍色值部分作爲辨析內容
        for (int i = 0; i < data.length; i++) {
            this.bitmapPixels[i] = (byte) data[i];
        }
    }

    @Override
    public byte[] getMatrix() {
        // 返回我們生成好的像素數據
        return bitmapPixels;
    }

    @Override
    public byte[] getRow(int y, byte[] row) {
        // 這裏要得到指定行的像素數據
        System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
        return row;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章