У меня есть приложение, в которое встроен zxing. Я пытался сохранить фотографию при сканировании QR-кода. Шон Оуэн рекомендовал следующее:
«Приложение получает непрерывный поток кадров с камеры для анализа. Вы можете сохранить любой из них, перехватив их в обратном вызове предварительного просмотра».
Насколько мне известно, единственные экземпляры обратного вызова предварительного просмотра находятся в действии CameraManager.java (https://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/camera/CameraManager.java).
Особенно:
public synchronized void requestPreviewFrame(Handler handler, int message) {
Camera theCamera = camera;
if (theCamera != null && previewing) {
previewCallback.setHandler(handler, message);
theCamera.setOneShotPreviewCallback(previewCallback);
}}
Поскольку это выполняется в каждом кадре, у меня нет метода сохранения (предпочтительно в виде даты байта) любого конкретного кадра. Я бы предположил, что есть точка, в которой что-то передается обратно в класс CaptureActivity.java (ссылка внизу), однако я сам ничего не нашел.
Любой, кто использовал Zxing, знает, что после сканирования на экране данных сканирования отображается призрачное изображение, если есть возможность взломать эту часть кода и преобразовать и/или сохранить эти данные в виде байтового кода, что также может быть полезно .
Любая помощь или другие идеи будут очень признательны. На запросы о любой дополнительной информации ответят быстро. Спасибо.
Полный код доступен в этой папке: https://code.google.com/p/zxing/source/browse/trunk#trunk%2Fandroid%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid
Обновлять:
На данный момент следующие разделы кода кажутся возможными местами для сохранения байтовых данных, оба находятся в классе DecodeHandler.java.
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
//here?
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
}
Handler handler = activity.getHandler();
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
Log.d(TAG, "Found barcode in " + (end - start) + " ms");
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
Bundle bundle = new Bundle();
Bitmap grayscaleBitmap = toBitmap(source, source.renderCroppedGreyscaleBitmap());
//I believe this bitmap is the one shown on screen after a scan has been performed
bundle.putParcelable(DecodeThread.BARCODE_BITMAP, grayscaleBitmap);
message.setData(bundle);
message.sendToTarget();
}
} else {
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_failed);
message.sendToTarget();
}
}}
private static Bitmap toBitmap(LuminanceSource source, int[] pixels) {
int width = source.getWidth();
int height = source.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
//saving the bitmnap at this point or slightly sooner, before grey scaling could work.
return bitmap;}
Обновление: запрошенный код найден в PreviewCallback.java.
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
}