Skip to content

Commit

Permalink
[#4] Android UI doesn't support Portrait and is small
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyVerbruggen authored and trongrg committed May 13, 2015
1 parent 4e5af0c commit a250540
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
bin/
.classpath
.project
*.iml
local.properties
1 change: 0 additions & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity
android:name="com.google.zxing.client.android.CaptureActivity"
android:screenOrientation="landscape"
android:clearTaskOnLaunch="true"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
Expand Down
2 changes: 1 addition & 1 deletion src/android/LibraryProject/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@

<application android:icon="@drawable/launcher_icon"
android:label="@string/app_name">

<activity android:name=".CaptureActivity"
android:screenOrientation="landscape"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:configChanges="orientation|keyboardHidden"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public PlanarYUVLuminanceSource(byte[] yuvData,
super(width, height);

if (left + width > 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@

package com.google.zxing.client.android.camera;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.graphics.Rect;
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.Window;
import android.view.WindowManager;

import com.google.zxing.client.android.PreferencesActivity;
Expand All @@ -48,11 +54,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;
}

/**
Expand All @@ -62,23 +70,43 @@ 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 {
if (display.getRotation() == Surface.ROTATION_0) {
height -= 40 * displayMetrics.density;
} else {
height -= 48 * displayMetrics.density;
}
}
screenResolution = new Point(width, height);
// height -= statusBarHeight();
// height -= 40; // statusBarHeight();

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 of screen orientation
WindowManager manager = (WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE);
int rotation = manager.getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_0) {
camera.setDisplayOrientation(90);
}

Camera.Parameters parameters = camera.getParameters();

if (parameters == null) {
Expand Down Expand Up @@ -260,5 +288,12 @@ private static String findSettableValue(Collection<String> supportedValues,
Log.i(TAG, "Settable value: " + result);
return result;
}

/*
private int statusBarHeight() {
Window window = this.activity.getWindow();
Rect rect = new Rect();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
return rect.top;
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import android.hardware.Camera;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.client.android.camera.open.OpenCameraManager;

Expand All @@ -41,8 +44,8 @@ public final class CameraManager {

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 MAX_FRAME_WIDTH = 960;
private static final int MAX_FRAME_HEIGHT = 700;

private final Context context;
private final CameraConfigurationManager configManager;
Expand All @@ -54,16 +57,19 @@ 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.
*/
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);
}

/**
Expand Down Expand Up @@ -223,8 +229,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;
Expand All @@ -247,10 +255,25 @@ 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;
// 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;

Display display = windowManager.getDefaultDisplay();
int rotation = display.getRotation();
if (rotation == Surface.ROTATION_0) {
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;
Expand All @@ -265,16 +288,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 {
Expand All @@ -293,13 +307,30 @@ public synchronized void setManualFramingRect(int width, int height) {
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
// Hack of orientation
Display display = windowManager.getDefaultDisplay();
int rotation = display.getRotation();

byte[] rotatedData = new byte[data.length];
if (rotation == Surface.ROTATION_0) {
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 == Surface.ROTATION_0 ? rotatedData: data, width, height, rect.left, rect.top,
rect.width(), rect.height(), false);
}

}

0 comments on commit a250540

Please sign in to comment.