Zxing掃描和生成二維碼+butterknife8.0之後的引用+將drawable文件夾下的圖片轉換成Drawable

Zxing掃描和生成二維碼+butterknife8.0之後的引用

**最近項目中用到二維碼掃描和生成使用到了Zxing這裏記錄下來:
先貼官方地址:**官網地址 開源中國 github.

項目下載地址http://download.csdn.net/detail/u010023795/9679251

  • 我這裏只集成了掃碼和二維碼生成的功能這裏主要用到的兩個類:CaptureActivity 掃描和EncodingUtils生成:
  • * /*
    public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {

    private static final String TAG = CaptureActivity.class.getSimpleName();

    private CameraManager cameraManager;
    private CaptureActivityHandler handler;
    private InactivityTimer inactivityTimer;
    private BeepManager beepManager;

    private SurfaceView scanPreview = null;
    private RelativeLayout scanContainer;
    private RelativeLayout scanCropView;
    private ImageView scanLine;

    private Rect mCropRect = null;
    private boolean isHasSurface = false;

    public Handler getHandler() {
    return handler;
    }

    public CameraManager getCameraManager() {
    return cameraManager;
    }

    @Override
    public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_capture);
    
    scanPreview = (SurfaceView) findViewById(R.id.capture_preview);
    scanContainer = (RelativeLayout) findViewById(R.id.capture_container);
    scanCropView = (RelativeLayout) findViewById(R.id.capture_crop_view);
    scanLine = (ImageView) findViewById(R.id.capture_scan_line);
    
    inactivityTimer = new InactivityTimer(this);
    beepManager = new BeepManager(this);
    
    TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation
            .RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
            0.9f);
    animation.setDuration(4500);
    animation.setRepeatCount(-1);
    animation.setRepeatMode(Animation.RESTART);
    scanLine.startAnimation(animation);
    

    }

    @Override
    protected void onResume() {
    super.onResume();

    // CameraManager must be initialized here, not in onCreate(). This is
    // necessary because we don't
    // want to open the camera driver and measure the screen size if we're
    // going to show the help on
    // first launch. That led to bugs where the scanning rectangle was the
    // wrong size and partially
    // off screen.
    cameraManager = new CameraManager(getApplication());
    
    
    handler = null;
    
    if (isHasSurface) {
        // The activity was paused but not stopped, so the surface still
        // exists. Therefore
        // surfaceCreated() won't be called, so init the camera here.
        initCamera(scanPreview.getHolder());
    } else {
        // Install the callback and wait for surfaceCreated() to init the
        // camera.
        scanPreview.getHolder().addCallback(this);
    }
    
    inactivityTimer.onResume();
    

    }

    @Override
    protected void onPause() {
    if (handler != null) {
    handler.quitSynchronously();
    handler = null;
    }
    inactivityTimer.onPause();
    beepManager.close();
    cameraManager.closeDriver();
    if (!isHasSurface) {
    scanPreview.getHolder().removeCallback(this);
    }
    super.onPause();
    }

    @Override
    protected void onDestroy() {
    inactivityTimer.shutdown();
    super.onDestroy();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    if (holder == null) {
    Log.e(TAG, “* WARNING * surfaceCreated() gave us a null surface!”);
    }
    if (!isHasSurface) {
    isHasSurface = true;
    initCamera(holder);
    }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    isHasSurface = false;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    /**

    • A valid barcode has been found, so give an indication of success and show
    • the results.
      *
    • @param rawResult The contents of the barcode.
    • @param bundle The extras
      */
      public void handleDecode(Result rawResult, Bundle bundle) {
      inactivityTimer.onActivity();
      beepManager.playBeepSoundAndVibrate();
      /*
      這裏是掃描成功之後返回數據給界面,需要返回的數據在這裏添加
      */
      Intent resultIntent = new Intent();
      bundle.putInt(“width”, mCropRect.width()); //返回生成二維碼掃描框的寬
      bundle.putInt(“height”, mCropRect.height());//返回生成二維碼掃描框的高
      bundle.putString(“result”, rawResult.getText());//返回二維碼的內容
      resultIntent.putExtras(bundle);
      this.setResult(RESULT_OK, resultIntent);
      CaptureActivity.this.finish();
      }

    private void initCamera(SurfaceHolder surfaceHolder) {
    if (surfaceHolder == null) {
    throw new IllegalStateException(“No SurfaceHolder provided”);
    }
    if (cameraManager.isOpen()) {
    Log.w(TAG, “initCamera() while already open – late SurfaceView callback?”);
    return;
    }
    try {
    cameraManager.openDriver(surfaceHolder);
    // Creating the handler starts the preview, which can also throw a
    // RuntimeException.
    if (handler == null) {
    handler = new CaptureActivityHandler(this, cameraManager, DecodeThread.ALL_MODE);
    }

        initCrop();
    } catch (IOException ioe) {
        Log.w(TAG, ioe);
        displayFrameworkBugMessageAndExit();
    } catch (RuntimeException e) {
        // Barcode Scanner has seen crashes in the wild of this variety:
        // java.?lang.?RuntimeException: Fail to connect to camera service
        Log.w(TAG, "Unexpected error initializing camera", e);
        displayFrameworkBugMessageAndExit();
    }
    

    }

    private void displayFrameworkBugMessageAndExit() {
    // camera error
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(getString(R.string.app_name));
    builder.setMessage(“Camera error”);
    builder.setPositiveButton(“OK”, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            finish();
        }
    
    });
    builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
    
        @Override
        public void onCancel(DialogInterface dialog) {
            finish();
        }
    });
    builder.show();
    

    }

    public void restartPreviewAfterDelay(long delayMS) {
    if (handler != null) {
    handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
    }
    }

    public Rect getCropRect() {
    return mCropRect;
    }

    /**

    • 初始化截取的矩形區域
      */
      private void initCrop() {
      int cameraWidth = cameraManager.getCameraResolution().y;
      int cameraHeight = cameraManager.getCameraResolution().x;

      /* 獲取佈局中掃描框的位置信息 /
      int[] location = new int[2];
      scanCropView.getLocationInWindow(location);

      int cropLeft = location[0];
      int cropTop = location[1] - getStatusBarHeight();

      int cropWidth = scanCropView.getWidth();
      int cropHeight = scanCropView.getHeight();

      /* 獲取佈局容器的寬高 /
      int containerWidth = scanContainer.getWidth();
      int containerHeight = scanContainer.getHeight();

      /* 計算最終截取的矩形的左上角頂點x座標 /
      int x = cropLeft * cameraWidth / containerWidth;
      /* 計算最終截取的矩形的左上角頂點y座標 /
      int y = cropTop * cameraHeight / containerHeight;

      /* 計算最終截取的矩形的寬度 /
      int width = cropWidth * cameraWidth / containerWidth;
      /* 計算最終截取的矩形的高度 /
      int height = cropHeight * cameraHeight / containerHeight;

      /* 生成最終的截取的矩形 /
      mCropRect = new Rect(x, y, width + x, height + y);
      }
      private int getStatusBarHeight() {
      try {
      Class <> c = Class.forName(“com.android.internal.R$dimen”);//class<>裏面爲?
      Object obj = c.newInstance();
      Field field = c.getField(“status_bar_height”);
      int x = Integer.parseInt(field.get(obj).toString());
      return getResources().getDimensionPixelSize(x);
      } catch (Exception e) {
      e.printStackTrace();
      }
      return 0;
      }
      }


      下面是二維碼生成工具類:
      /**

      • 二維碼生成工具類
        */
        public class EncodingUtils {

    /**

    • 創建二維碼
      *
    • @param content content
    • @param widthPix widthPix
    • @param heightPix heightPix
    • @param logoBm logoBm
    • @return 二維碼
      */
      public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) {
      try {
      if (content == null || “”.equals(content)) {
      return null;
      }
      // 配置參數
      Map<> hints = new HashMap<>();//Map<>括號裏應該是EncodeHintType, Object不知道爲什麼csdn裏面這樣直接這樣寫會造成下面的內容全部不顯示
      hints.put(EncodeHintType.CHARACTER_SET, “utf-8”);
      // 容錯級別
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
      // 圖像數據轉換,使用了矩陣轉換
      BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
      heightPix, hints);
      int[] pixels = new int[widthPix * heightPix];
      // 下面這裏按照二維碼的算法,逐個生成二維碼的圖片,
      // 兩個for循環是圖片橫列掃描的結果
      for (int y = 0; y < heightPix; y++) {
      for (int x = 0; x < widthPix; x++) {
      if (bitMatrix.get(x, y)) {
      pixels[y * widthPix + x] = 0xff000000;
      } else {
      pixels[y * widthPix + x] = 0xffffffff;
      }
      }
      }
      // 生成二維碼圖片的格式,使用ARGB_8888
      Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
      bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
      if (logoBm != null) {
      bitmap = addLogo(bitmap, logoBm);
      }
      //必須使用compress方法將bitmap保存到文件中再進行讀取。直接返回的bitmap是沒有任何壓縮的,內存消耗巨大!
      return bitmap;
      } catch (WriterException e) {
      e.printStackTrace();
      }
      return null;
      }

    /**

    • 在二維碼中間添加Logo圖案
      */
      private static Bitmap addLogo(Bitmap src, Bitmap logo) {
      if (src == null) {
      return null;
      }
      if (logo == null) {
      return src;
      }
      //獲取圖片的寬高
      int srcWidth = src.getWidth();
      int srcHeight = src.getHeight();
      int logoWidth = logo.getWidth();
      int logoHeight = logo.getHeight();
      if (srcWidth == 0 || srcHeight == 0) {
      return null;
      }
      if (logoWidth == 0 || logoHeight == 0) {
      return src;
      }
      //logo大小爲二維碼整體大小的1/5
      float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
      Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
      try {
      Canvas canvas = new Canvas(bitmap);
      canvas.drawBitmap(src, 0, 0, null);
      canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
      canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
      canvas.save(Canvas.ALL_SAVE_FLAG);
      canvas.restore();
      } catch (Exception e) {
      bitmap = null;
      e.getStackTrace();
      }
      return bitmap;
      }
      }

這些類都是Zxing裏面的,自己可以根據需要去封裝。

封裝好了類之後其實我們的調用就很簡單了只需要寫一個Activity。
public class MainActivity extends AppCompatActivity {

@BindView(R.id.btn_camer)
Button btnCamer;
@BindView(R.id.tv_result)
TextView tvResult;
@BindView(R.id.et_qr_string)
EditText etQrString;
@BindView(R.id.btn_creat)
Button btnCreat;
@BindView(R.id.if_logo)
CheckBox ifLogo;
@BindView(R.id.iamge_show)
ImageView iamgeShow;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this); 

}


@OnClick({R.id.btn_camer, R.id.btn_creat, R.id.if_logo, R.id.iamge_show})
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_camer:
            startActivityForResult(new Intent(MainActivity.this, CaptureActivity.class),0);//啓動掃描界面
            break;
        case R.id.btn_creat:
            String str = etQrString.getText().toString();
            if (str.equals("")) {
                Toast.makeText(MainActivity.this, "不能爲空", Toast.LENGTH_SHORT).show();
            } else {
                // 位圖
                try {
                    /**
                     * 參數:1.文本 2 3.二維碼的寬高 4.二維碼中間的那個logo
                     */
                    Bitmap bitma = BitmapFactory.decodeResource(getResources(), R.drawable.zaizai);
                    Bitmap bitmap = EncodingUtils.createQRCode(str, 700, 700,bitma);
                    // 設置圖片
                    iamgeShow.setImageBitmap(bitmap);
                    Toast.makeText(this,"55555"+str,Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Toast.makeText(this,"55555",Toast.LENGTH_SHORT).show();
            break;
        case R.id.if_logo:
            break;
        case R.id.iamge_show:
            break;
    }
}
/*
掃描成功之後返回二維碼的信息在這裏接收處理
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        String result = data.getExtras().getString("result");
        Toast.makeText(this,result+"1",Toast.LENGTH_SHORT).show();
        tvResult.setText(result);
    }
}

}

二維碼生成和掃描就這麼寫完了,但是在運行的時候竟然報控件空指針錯誤,就是說我的控件都是沒有生成找不到的在運行的時候,但是我明明用了ButterKnife也添加進去了還可以自動生成,但是註解運行的時候就是沒成功。後來找到了資料,原來在ButterKnife8.0以後引用發生了改變。現在必需多做幾道程序下面請看圖:
先把官網地址貼出來:http://jakewharton.github.io/butterknife/
github:https://github.com/JakeWharton/butterknife
這裏寫圖片描述
接下來我們打開第一個gradle
添加classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
這裏寫圖片描述
第二步打開第二個gradle
apply plugin: ‘com.neenbedankt.android-apt’
compile ‘com.jakewharton:butterknife:8.4.0’
apt ‘com.jakewharton:butterknife-compiler:8.4.0’
這裏寫圖片描述
最後注意添加的版本是不是一致,兩個gradle中Butter Knife版本必須一致。最後重新 clean project就完成了。
參考:http://www.cnblogs.com/zzw1994/p/5197758.html

將drawable下的圖片轉換成bitmap
1、 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.xxx);

2、Resources r = this.getContext().getResources();
Inputstream is = r.openRawResource(R.drawable.xxx);
BitmapDrawable bmpDraw = new BitmapDrawable(is);
Bitmap bmp = bmpDraw.getBitmap();

3、Resources r = this.getContext().getResources();
Bitmap bmp=BitmapFactory.decodeResource(r, R.drawable.icon);
Bitmap bmp = Bitmap.createBitmap( 300, 300, Config.ARGB_8888 );

將drawable下的圖片轉換成Drawable
Resources resources = mContext.getResources();
Drawable drawable = resources.getDrawable(R.drawable.a);
imageview.setBackground(drawable);

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