下面列出了怎么用com.google.zxing.PlanarYUVLuminanceSource的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* 使用YUV解析bitmap
*
* @param data
* @param width
* @param height
* @param hintTypeMap
* @return
*/
private Result decodeFromYUV(int[] data, int width, int height, Map<DecodeHintType, ?> hintTypeMap) {
Result result = null;
byte[] yuv = convertRGBToYuv(data, new byte[width * height], width, height);
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(yuv, width, height, 0, 0, width, height, false);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
result = new MultiFormatReader().decode(binaryBitmap, hintTypeMap);
} catch (NotFoundException e) {
//使用GlobalHistogramBinarizer算法进行解析
try {
result = new MultiFormatReader().decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)), hintTypeMap);
} catch (NotFoundException e1) {
e1.printStackTrace();
}
}
return result;
}
/**
* Decode barcode from YUV pixels array
*
* @param pixels YUV image data
* @param width Image width
* @param height Image height
* @param rotation Degrees to rotate image before decoding (only 0, 90, 180 or 270 are allowed)
* @param reverseHorizontal Reverse image horizontally before decoding
* @param hints Decoder hints
* @return Decode result, if barcode was decoded successfully, {@code null} otherwise
* @see DecodeHintType
*/
@Nullable
@SuppressWarnings("SuspiciousNameCombination")
public static Result decodeYuv(@NonNull final byte[] pixels, final int width, final int height,
@Rotation final int rotation, final boolean reverseHorizontal,
@Nullable final Map<DecodeHintType, ?> hints) {
Objects.requireNonNull(pixels);
final byte[] rotatedPixels = Utils.rotateYuv(pixels, width, height, rotation);
final int rotatedWidth;
final int rotatedHeight;
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
rotatedWidth = height;
rotatedHeight = width;
} else {
rotatedWidth = width;
rotatedHeight = height;
}
final MultiFormatReader reader = createReader(hints);
try {
return Utils.decodeLuminanceSource(reader,
new PlanarYUVLuminanceSource(rotatedPixels, rotatedWidth, rotatedHeight, 0, 0,
rotatedWidth, rotatedHeight, reverseHorizontal));
} catch (final ReaderException e) {
return null;
}
}
@Nullable
@SuppressWarnings("SuspiciousNameCombination")
public Result decode(@NonNull final MultiFormatReader reader) throws ReaderException {
int imageWidth = mImageSize.getX();
int imageHeight = mImageSize.getY();
final int orientation = mOrientation;
final byte[] image = Utils.rotateYuv(mImage, imageWidth, imageHeight, orientation);
if (orientation == 90 || orientation == 270) {
final int width = imageWidth;
imageWidth = imageHeight;
imageHeight = width;
}
final Rect frameRect =
Utils.getImageFrameRect(imageWidth, imageHeight, mViewFrameRect, mPreviewSize,
mViewSize);
final int frameWidth = frameRect.getWidth();
final int frameHeight = frameRect.getHeight();
if (frameWidth < 1 || frameHeight < 1) {
return null;
}
return Utils.decodeLuminanceSource(reader,
new PlanarYUVLuminanceSource(image, imageWidth, imageHeight, frameRect.getLeft(),
frameRect.getTop(), frameWidth, frameHeight, mReverseHorizontal));
}
/**
* A factory method to build the appropriate LuminanceSource object based on
* the format of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data,
int width, int height) {
Rect rect = getFramingRectInPreview();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
if (config == null) {
config = new ZxingConfig();
}
if (config.isFullScreenScan()) {
return new PlanarYUVLuminanceSource(data, width, height, 0,
0, width, height, false);
} else {
int actionbarHeight = context.getResources().getDimensionPixelSize(R.dimen.toolBarHeight);
return new PlanarYUVLuminanceSource(data, width, height, rect.left,
rect.top + actionbarHeight, rect.width(), rect.height(), false);
}
}
public static Result decodeImage(final String path) {
Bitmap bitmap = QrUtils.decodeSampledBitmapFromFile(path, 256, 256);
// Google Photo 相册中选取云照片是会出现 Bitmap == null
if (bitmap == null) return null;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
// RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
PlanarYUVLuminanceSource source1 = new PlanarYUVLuminanceSource(getYUV420sp(width, height, bitmap), width, height, 0, 0, width, height, false);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source1));
// BinaryBitmap binaryBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source1));
HashMap<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
try {
return new MultiFormatReader().decode(binaryBitmap, hints);
} catch (NotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
if (rect == null) {
return null;
}
//this if saves the app from crashing when switching orientation........
//finally debugged the biggest problem ...yippee
if (rect.left + rect.width() > width || rect.top + rect.height() > height)
return new PlanarYUVLuminanceSource(data, height, width, rect.left, rect.top,
rect.width(), rect.height(), false);
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
}
public String decodeWithZxing(byte[] data, int width, int height, Rect crop) {
MultiFormatReader multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(changeZXingDecodeDataMode());
Result rawResult = null;
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height,
crop.left, crop.top, crop.width(), crop.height(), false);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
}
return rawResult != null ? rawResult.getText() : null;
}
private String decode(byte[] data, int width, int height) {
ScannerManager manager = mManager.get();
if (manager == null) {
return null;
}
Rect rect = manager.getFramingRectInPreview();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data,
width, height, rect.left, rect.top, rect.right, rect.bottom, false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
try {
Result result = reader.decode(bitmap, mHints);
return result.getText();
} catch (ReaderException e) {
// Ignore as we will repeatedly decode the preview frame
return null;
}
}
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] rotatedData, int width, int height, boolean horizontal) {
Rect rect = getFramingRectInPreview(horizontal);
int previewFormat = mCameraConfig.getPreviewFormat();
String previewFormatString = mCameraConfig.getPreviewFormatString();
switch (previewFormat) {
// This is the standard Android format which all devices are REQUIRED to support.
// In theory, it's the only one we should ever care about.
case PixelFormat.YCbCr_420_SP:
// This format has never been seen in the wild, but is compatible as we only care
// about the Y channel, so allow it.
case PixelFormat.YCbCr_422_SP:
return new PlanarYUVLuminanceSource(rotatedData, width, height, rect.left, rect.top,
rect.width(), rect.height(), horizontal);
default:
// The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
// Fortunately, it too has all the Y data up front, so we can read it.
if ("yuv420p".equals(previewFormatString)) {
return new PlanarYUVLuminanceSource(rotatedData, width, height, rect.left, rect.top,
rect.width(), rect.height(), horizontal);
}
}
throw new IllegalArgumentException("Unsupported picture format: " +
previewFormat + '/' + previewFormatString);
}
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
byte[] rotatedData = new byte[data.length];
int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;
if (rotation == Configuration.ORIENTATION_PORTRAIT) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
}
int tmp = width;
//noinspection SuspiciousNameCombination
width = height;
height = tmp;
} else {
rotatedData = null;
}
Rect rect = getFramingRectInPreview();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(rotation == Configuration.ORIENTATION_PORTRAIT ? rotatedData : data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
}
private void decode(final byte[] data) {
final PlanarYUVLuminanceSource source = cameraManager.buildLuminanceSource(data);
final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, (ResultPointCallback) dot -> runOnUiThread(() -> scannerView.addDot(dot)));
final Result scanResult = reader.decode(bitmap, hints);
runOnUiThread(() -> handleResult(scanResult));
} catch (final ReaderException x) {
// retry
cameraHandler.post(fetchAndDecodeRunnable);
} finally {
reader.reset();
}
}
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
byte[] rotatedData = new byte[data.length];
int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;
if (rotation == Configuration.ORIENTATION_PORTRAIT) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
}
int tmp = width;
width = height;
height = tmp;
} else {
rotatedData = null;
}
Rect rect = getFramingRectInPreview();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(rotation == Configuration.ORIENTATION_PORTRAIT ? rotatedData : data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
}
private PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
if (barCodeScanConfig == null) return null;
Rect borders = barCodeScanConfig.getROI();
if (borders == null) return null;
return new PlanarYUVLuminanceSource(data, width, height, borders.left, borders.top,
borders.width(), borders.height(), false);
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
}
/**
* A factory method to build the appropriate LuminanceSource object based on
* the format of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = activity.getCropRect();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect
.height(), false);
}
/**
* 处理缩略图
* @param source {@link PlanarYUVLuminanceSource}
* @param bundle 存储数据 {@link Bundle}
*/
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeConfig.BARCODE_BITMAP, out.toByteArray());
}
/**
* A factory method to build the appropriate LuminanceSource object based on
* the format of the preview buffers, as described by Camera.Parameters.
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
if (mDecodeConfig == null) {
return null;
}
DevLogger.dTag(TAG, "buildLuminanceSource - 解析摄像头数据");
// 判断是否裁减
if (mDecodeConfig.isCropRect() && mDecodeConfig.getCropRect() != null) {
// 判断是否出现异常
if (mDecodeConfig.isError()) {
return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
} else {
try {
// 获取裁减识别区域
Rect rect = mDecodeConfig.getCropRect();
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height(), false);
} catch (Exception e) { // 出现异常时, 使用全屏
// 设置异常
mDecodeConfig.setError(true, e);
// 全屏处理
return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
}
}
} else {
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
}
}
@Override
public WritableMap decodeNV21Data(byte[] data, int width, int height, int rotation) {
byte[] yuv;
int temp;
switch (rotation) {
case 90:
yuv = RNLBarCodeUtils.rotateYUV90(data, width, height);
temp = width;
width = height;
height = temp;
break;
case 180:
yuv = RNLBarCodeUtils.rotateYUV180(data, width, height);
break;
case 270:
yuv = RNLBarCodeUtils.rotateYUV270(data, width, height);
temp = width;
width = height;
height = temp;
break;
default:
yuv = data;
}
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
yuv, width, height, 0, 0, width, height, false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
WritableMap result = null;
try {
Result decodeResult = mReader.decode(bitmap, mHints);
result = Arguments.createMap();
result.putInt("format", symbolToFormat(decodeResult.getBarcodeFormat()));
result.putString("content", decodeResult.getText());
} catch (NotFoundException ignored) {
}
return result;
}
private void decode(final byte[] data)
{
final PlanarYUVLuminanceSource source = cameraManager.buildLuminanceSource(data);
final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK,
(ResultPointCallback) dot -> runOnUiThread(() -> scannerView.addDot(dot)));
final Result scanResult = reader.decode(bitmap, hints);
final int thumbnailWidth = source.getThumbnailWidth();
final int thumbnailHeight = source.getThumbnailHeight();
final float thumbnailScaleFactor = (float) thumbnailWidth / source.getWidth();
final Bitmap thumbnailImage = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight,
Bitmap.Config.ARGB_8888);
thumbnailImage.setPixels(
source.renderThumbnail(), 0, thumbnailWidth, 0, 0, thumbnailWidth, thumbnailHeight);
runOnUiThread(() -> handleResult(scanResult, thumbnailImage, thumbnailScaleFactor));
} catch (final ReaderException x) {
// retry
cameraHandler.post(fetchAndDecodeRunnable);
} finally {
reader.reset();
}
}
private void decode(final byte[] data)
{
final PlanarYUVLuminanceSource source = cameraManager.buildLuminanceSource(data);
final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK,
(ResultPointCallback) dot -> runOnUiThread(() -> scannerView.addDot(dot)));
final Result scanResult = reader.decode(bitmap, hints);
Log.d(TAG,"scanResult " + scanResult);
final int thumbnailWidth = source.getThumbnailWidth();
final int thumbnailHeight = source.getThumbnailHeight();
final float thumbnailScaleFactor = (float) thumbnailWidth / source.getWidth();
final Bitmap thumbnailImage = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight,
Bitmap.Config.ARGB_8888);
thumbnailImage.setPixels(
source.renderThumbnail(), 0, thumbnailWidth, 0, 0, thumbnailWidth, thumbnailHeight);
runOnUiThread(() -> handleResult(scanResult, thumbnailImage, thumbnailScaleFactor));
} catch (final ReaderException x) {
// retry
cameraHandler.post(fetchAndDecodeRunnable);
} finally {
reader.reset();
}
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source,
Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height,
Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width
/ source.getWidth());
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source,
Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height,
Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width
/ source.getWidth());
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth());
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
}
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
}
/**
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, reuse the same reader
* objects from one decode to the next.
*/
public static Result decodeImage(byte[] data, int width, int height) {
// 处理
Result result = null;
try {
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
PlanarYUVLuminanceSource source =
new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
/**
* HybridBinarizer算法使用了更高级的算法,但使用GlobalHistogramBinarizer识别效率确实比HybridBinarizer要高一些。
*
* GlobalHistogram算法:(http://kuangjianwei.blog.163.com/blog/static/190088953201361015055110/)
*
* 二值化的关键就是定义出黑白的界限,我们的图像已经转化为了灰度图像,每个点都是由一个灰度值来表示,就需要定义出一个灰度值,大于这个值就为白(0),低于这个值就为黑(1)。
* 在GlobalHistogramBinarizer中,是从图像中均匀取5行(覆盖整个图像高度),每行取中间五分之四作为样本;以灰度值为X轴,每个灰度值的像素个数为Y轴建立一个直方图,
* 从直方图中取点数最多的一个灰度值,然后再去给其他的灰度值进行分数计算,按照点数乘以与最多点数灰度值的距离的平方来进行打分,选分数最高的一个灰度值。接下来在这两个灰度值中间选取一个区分界限,
* 取的原则是尽量靠近中间并且要点数越少越好。界限有了以后就容易了,与整幅图像的每个点进行比较,如果灰度值比界限小的就是黑,在新的矩阵中将该点置1,其余的就是白,为0。
*/
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
// BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader2 = new QRCodeReader();
result = reader2.decode(bitmap1, hints);
} catch (ReaderException e) {
}
return result;
}
/**
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, reuse the same reader
* objects from one decode to the next.
*/
public static Result decodeImage(byte[] data, int width, int height) {
// 处理
Result result = null;
try {
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
PlanarYUVLuminanceSource source =
new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);
/**
* HybridBinarizer算法使用了更高级的算法,但使用GlobalHistogramBinarizer识别效率确实比HybridBinarizer要高一些。
*
* GlobalHistogram算法:(http://kuangjianwei.blog.163.com/blog/static/190088953201361015055110/)
*
* 二值化的关键就是定义出黑白的界限,我们的图像已经转化为了灰度图像,每个点都是由一个灰度值来表示,就需要定义出一个灰度值,大于这个值就为白(0),低于这个值就为黑(1)。
* 在GlobalHistogramBinarizer中,是从图像中均匀取5行(覆盖整个图像高度),每行取中间五分之四作为样本;以灰度值为X轴,每个灰度值的像素个数为Y轴建立一个直方图,
* 从直方图中取点数最多的一个灰度值,然后再去给其他的灰度值进行分数计算,按照点数乘以与最多点数灰度值的距离的平方来进行打分,选分数最高的一个灰度值。接下来在这两个灰度值中间选取一个区分界限,
* 取的原则是尽量靠近中间并且要点数越少越好。界限有了以后就容易了,与整幅图像的每个点进行比较,如果灰度值比界限小的就是黑,在新的矩阵中将该点置1,其余的就是白,为0。
*/
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
// BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader2 = new QRCodeReader();
result = reader2.decode(bitmap1, hints);
} catch (ReaderException e) {
}
return result;
}
private static void bundleThumbnail(PlanarYUVLuminanceSource source, Bundle bundle) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
bundle.putByteArray(DecodeThread.BARCODE_BITMAP, out.toByteArray());
}
/**
* A factory method to build the appropriate LuminanceSource object based on
* the format of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
// 扫码区域大小,可以调整扫码区域大小
Rect rect = activity.getCropRect();
if (rect == null) {
return null;
}
// Go ahead and assume it's YUV rather than die.
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect
.height(), false);
}