diff --git a/.gitignore b/.gitignore index 4f3bcbbe2..6a8d7b256 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ bin/ .classpath .project +*.iml +local.properties diff --git a/plugin.xml b/plugin.xml index 05ff0d1e6..53679469b 100644 --- a/plugin.xml +++ b/plugin.xml @@ -68,7 +68,6 @@ + dataWidth || top + height > dataHeight) { - throw new IllegalArgumentException("Crop rectangle does not fit within image data."); +// throw new IllegalArgumentException("Crop rectangle does not fit within image data. Left:" + left + ", width:" + width + ", dataWidth:" + dataWidth + ", top:" + top + ", height:" + height + ", dataHeight:" + dataHeight); } this.yuvData = yuvData; diff --git a/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java b/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java index 30d244741..3265d6d33 100755 --- a/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java +++ b/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java @@ -16,6 +16,10 @@ package com.google.zxing.client.android; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.hardware.Camera; +import android.widget.Button; import com.google.zxing.BarcodeFormat; import com.google.zxing.Result; import com.google.zxing.ResultMetadataType; @@ -28,6 +32,7 @@ import com.google.zxing.client.android.result.ResultHandler; import com.google.zxing.client.android.result.ResultHandlerFactory; import com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever; +import com.google.zxing.client.android.share.BookmarkPickerActivity; import com.google.zxing.client.android.share.ShareActivity; import android.app.Activity; @@ -110,6 +115,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private Result savedResultToShow; private ViewfinderView viewfinderView; private TextView statusView; + private Button flipButton; private View resultView; private Result lastResult; private boolean hasSurface; @@ -136,6 +142,14 @@ CameraManager getCameraManager() { return cameraManager; } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + // recreate is required for cases when no targetSdkVersion has been set in AndroidManifest.xml + // and the orientation has changed + recreate(); + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); diff --git a/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java b/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java index fe0a7d9ad..2605adfcf 100644 --- a/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java +++ b/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java @@ -18,20 +18,19 @@ import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.graphics.Point; import android.hardware.Camera; import android.preference.PreferenceManager; +import android.util.DisplayMetrics; import android.util.Log; +import android.util.TypedValue; import android.view.Display; +import android.view.Surface; import android.view.WindowManager; - import com.google.zxing.client.android.PreferencesActivity; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** * A class which deals with reading, parsing, and setting the camera parameters which are used to @@ -48,11 +47,13 @@ final class CameraConfigurationManager { private static final int MAX_PREVIEW_PIXELS = 1280 * 720; private final Context context; + // private final Activity activity; private Point screenResolution; private Point cameraResolution; CameraConfigurationManager(Context context) { - this.context = context; + this.context = context.getApplicationContext(); +// this.activity = (Activity) context; } /** @@ -62,23 +63,57 @@ void initFromCameraParameters(Camera camera) { Camera.Parameters parameters = camera.getParameters(); WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); - int width = display.getWidth(); - int height = display.getHeight(); - // We're landscape-only, and have apparently seen issues with display thinking it's portrait - // when waking from sleep. If it's not landscape, assume it's mistaken and reverse them: - if (width < height) { - Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect"); - int temp = width; - width = height; - height = temp; + DisplayMetrics metrics = new DisplayMetrics(); + display.getMetrics(metrics); + + screenResolution = new Point(); + int width = metrics.widthPixels; + int height = metrics.heightPixels; + + // Remove action bar height + TypedValue typedValue = new TypedValue(); + DisplayMetrics displayMetrics = this.context.getResources().getDisplayMetrics(); + if (this.context.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) { + height -= TypedValue.complexToDimensionPixelSize(typedValue.data, displayMetrics); + } else { + int rotation = context.getApplicationContext().getResources().getConfiguration().orientation; + if (rotation == Configuration.ORIENTATION_PORTRAIT) { + height -= 40 * displayMetrics.density; + } else { + height -= 48 * displayMetrics.density; + } } - screenResolution = new Point(width, height); +// height -= statusBarHeight(); + height -= 50; + + screenResolution.set(width, height); + Log.i(TAG, "Screen resolution: " + screenResolution); cameraResolution = findBestPreviewSizeValue(parameters, screenResolution); Log.i(TAG, "Camera resolution: " + cameraResolution); } void setDesiredCameraParameters(Camera camera, boolean safeMode) { + // Checkout screen orientation + int rotation = context.getApplicationContext().getResources().getConfiguration().orientation; + + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display display = windowManager.getDefaultDisplay(); + int deviceSpecificRotation = display.getRotation(); + + if (rotation == Configuration.ORIENTATION_PORTRAIT) { + if (deviceSpecificRotation == Surface.ROTATION_0 || deviceSpecificRotation == Surface.ROTATION_90) { + camera.setDisplayOrientation(90); + } else { + camera.setDisplayOrientation(270); + } + } else { + // landscape + if (deviceSpecificRotation == Surface.ROTATION_180 || deviceSpecificRotation == Surface.ROTATION_270) { + camera.setDisplayOrientation(180); + } + } + Camera.Parameters parameters = camera.getParameters(); if (parameters == null) { @@ -100,19 +135,19 @@ void setDesiredCameraParameters(Camera camera, boolean safeMode) { if (prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true)) { if (safeMode || prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, false)) { focusMode = findSettableValue(parameters.getSupportedFocusModes(), - Camera.Parameters.FOCUS_MODE_AUTO); + Camera.Parameters.FOCUS_MODE_AUTO); } else { focusMode = findSettableValue(parameters.getSupportedFocusModes(), - "continuous-picture", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE in 4.0+ - "continuous-video", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO in 4.0+ - Camera.Parameters.FOCUS_MODE_AUTO); + "continuous-picture", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE in 4.0+ + "continuous-video", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO in 4.0+ + Camera.Parameters.FOCUS_MODE_AUTO); } } // Maybe selected auto-focus but not available, so fall through here: if (!safeMode && focusMode == null) { focusMode = findSettableValue(parameters.getSupportedFocusModes(), - Camera.Parameters.FOCUS_MODE_MACRO, - "edof"); // Camera.Parameters.FOCUS_MODE_EDOF in 2.2+ + Camera.Parameters.FOCUS_MODE_MACRO, + "edof"); // Camera.Parameters.FOCUS_MODE_EDOF in 2.2+ } if (focusMode != null) { parameters.setFocusMode(focusMode); @@ -152,11 +187,11 @@ private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolea String flashMode; if (newSetting) { flashMode = findSettableValue(parameters.getSupportedFlashModes(), - Camera.Parameters.FLASH_MODE_TORCH, - Camera.Parameters.FLASH_MODE_ON); + Camera.Parameters.FLASH_MODE_TORCH, + Camera.Parameters.FLASH_MODE_ON); } else { flashMode = findSettableValue(parameters.getSupportedFlashModes(), - Camera.Parameters.FLASH_MODE_OFF); + Camera.Parameters.FLASH_MODE_OFF); } if (flashMode != null) { parameters.setFlashMode(flashMode); @@ -241,6 +276,9 @@ public int compare(Camera.Size a, Camera.Size b) { Log.i(TAG, "No suitable preview sizes, using default: " + bestSize); } + WindowManager manager = (WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE); + int rotation = manager.getDefaultDisplay().getRotation(); + Log.i(TAG, "Found best approximate preview size: " + bestSize); return bestSize; } @@ -260,5 +298,4 @@ private static String findSettableValue(Collection supportedValues, Log.i(TAG, "Settable value: " + result); return result; } - } diff --git a/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraManager.java b/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraManager.java index 005d80789..55dbdf863 100755 --- a/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraManager.java +++ b/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraManager.java @@ -17,12 +17,14 @@ package com.google.zxing.client.android.camera; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.hardware.Camera; import android.os.Handler; import android.util.Log; import android.view.SurfaceHolder; +import android.view.WindowManager; import com.google.zxing.PlanarYUVLuminanceSource; import com.google.zxing.client.android.camera.open.OpenCameraManager; @@ -39,10 +41,10 @@ public final class CameraManager { private static final String TAG = CameraManager.class.getSimpleName(); - private static final int MIN_FRAME_WIDTH = 240; - private static final int MIN_FRAME_HEIGHT = 240; - private static final int MAX_FRAME_WIDTH = 600; - private static final int MAX_FRAME_HEIGHT = 400; + private static final int MIN_FRAME_WIDTH = 220; + private static final int MIN_FRAME_HEIGHT = 220; + private static final int MAX_FRAME_WIDTH = 880; + private static final int MAX_FRAME_HEIGHT = 680; private final Context context; private final CameraConfigurationManager configManager; @@ -54,6 +56,8 @@ public final class CameraManager { private boolean previewing; private int requestedFramingRectWidth; private int requestedFramingRectHeight; + private WindowManager windowManager; + /** * Preview frames are delivered here, which we pass on to the registered handler. Make sure to * clear the handler so it will only receive one message. @@ -61,9 +65,10 @@ public final class CameraManager { private final PreviewCallback previewCallback; public CameraManager(Context context) { - this.context = context; + this.context = context.getApplicationContext(); this.configManager = new CameraConfigurationManager(context); previewCallback = new PreviewCallback(configManager); + windowManager = (WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE); } /** @@ -223,8 +228,10 @@ public synchronized Rect getFramingRect() { height = MAX_FRAME_HEIGHT; } int leftOffset = (screenResolution.x - width) / 2; - int topOffset = (screenResolution.y - height) / 2; - framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); + int topOffset, bottomOffset; + topOffset = (screenResolution.y - height) / 2; + bottomOffset = topOffset + height; + framingRect = new Rect(leftOffset, topOffset, leftOffset + width, bottomOffset); Log.d(TAG, "Calculated framing rect: " + framingRect); } return framingRect; @@ -247,10 +254,20 @@ public synchronized Rect getFramingRectInPreview() { // Called early, before init even finished return null; } - rect.left = rect.left * cameraResolution.x / screenResolution.x; - rect.right = rect.right * cameraResolution.x / screenResolution.x; - rect.top = rect.top * cameraResolution.y / screenResolution.y; - rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y; + + int rotation = context.getApplicationContext().getResources().getConfiguration().orientation; + if (rotation == Configuration.ORIENTATION_PORTRAIT) { + rect.left = rect.left * cameraResolution.y / screenResolution.x; + rect.right = rect.right * cameraResolution.y / screenResolution.x; + rect.top = rect.top * cameraResolution.x / screenResolution.y; + rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y; + } else { + rect.left = rect.left * cameraResolution.x / screenResolution.x; + rect.right = rect.right * cameraResolution.x / screenResolution.x; + rect.top = rect.top * cameraResolution.y / screenResolution.y; + rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y; + } + framingRectInPreview = rect; } return framingRectInPreview; @@ -265,16 +282,7 @@ public synchronized Rect getFramingRectInPreview() { */ public synchronized void setManualFramingRect(int width, int height) { if (initialized) { - Point screenResolution = configManager.getScreenResolution(); - if (width > screenResolution.x) { - width = screenResolution.x; - } - if (height > screenResolution.y) { - height = screenResolution.y; - } - int leftOffset = (screenResolution.x - width) / 2; - int topOffset = (screenResolution.y - height) / 2; - framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); + framingRect = getFramingRect(); Log.d(TAG, "Calculated manual framing rect: " + framingRect); framingRectInPreview = null; } else { @@ -283,23 +291,28 @@ public synchronized void setManualFramingRect(int width, int height) { } } - /** - * 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; + 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(data, width, height, rect.left, rect.top, - rect.width(), rect.height(), false); + return new PlanarYUVLuminanceSource(rotation == Configuration.ORIENTATION_PORTRAIT ? rotatedData : data, width, height, rect.left, rect.top, + rect.width(), rect.height(), false); } - } diff --git a/src/android/com.google.zxing.client.android.captureactivity.jar b/src/android/com.google.zxing.client.android.captureactivity.jar index ec06ea617..598b913dd 100644 Binary files a/src/android/com.google.zxing.client.android.captureactivity.jar and b/src/android/com.google.zxing.client.android.captureactivity.jar differ diff --git a/src/ios/CDVBarcodeScanner.mm b/src/ios/CDVBarcodeScanner.mm index 2105d457c..8a8d36e0f 100644 --- a/src/ios/CDVBarcodeScanner.mm +++ b/src/ios/CDVBarcodeScanner.mm @@ -63,6 +63,7 @@ @interface CDVbcsProcessor : NSObject treshold) { + [self.results removeObjectAtIndex:0]; + } + + if (self.results.count < treshold) + { + return NO; + } + + BOOL allEqual = YES; + NSString *compareString = [self.results objectAtIndex:0]; + + for (NSString *aResult in self.results) + { + if (![compareString isEqualToString:aResult]) + { + allEqual = NO; + //NSLog(@"Did not fit: %@",self.results); + break; + } + } + + return allEqual; +} + //-------------------------------------------------------------------------- - (void)barcodeScanSucceeded:(NSString*)text format:(NSString*)format { dispatch_sync(dispatch_get_main_queue(), ^{ @@ -495,7 +527,11 @@ - (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMS const char* cString = resultText->getText().c_str(); NSString* resultString = [[NSString alloc] initWithCString:cString encoding:NSUTF8StringEncoding]; - [self barcodeScanSucceeded:resultString format:format]; + if ([self checkResult:resultString]) { + [self barcodeScanSucceeded:resultString format:format]; + } + + } catch (zxing::ReaderException &rex) { @@ -778,7 +814,7 @@ - (id)initWithProcessor:(CDVbcsProcessor*)processor alternateOverlay:(NSString * //-------------------------------------------------------------------------- - (void)dealloc { self.view = nil; -// self.processor = nil; + self.processor = nil; self.shutterPressed = NO; self.alternateXib = nil; self.overlayView = nil;