I want to show portrait orientation on Zxing's camera.
How can this be done?
Here's how it works.
Step 1: Add following lines to rotate data before buildLuminanceSource(..) in decode(byte[] data, int width, int height)
DecodeHandler.java:
byte[] rotatedData = new byte[data.length];
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;
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
Step 2: Modify getFramingRectInPreview().
CameraManager.java
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;
Step 3: Disable the check for Landscape Mode in initFromCameraParameters(...)
CameraConfigurationManager.java
//remove the following
if (width < height) {
Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
int temp = width;
width = height;
height = temp;
}
Step 4: Add following line to rotate camera insetDesiredCameraParameters(...)
CameraConfigurationManager.java
camera.setDisplayOrientation(90);
Step 5: Do not forget to set orientation of activity to portrait. I.e: manifest
To support all orientation and change automatically when rotating the activity do this, all you have to modify is the CameraManager.javaclass.
And remove this method getCurrentOrientation() from CaptureActivity.java
In CameraManager.java Create this variable:
int resultOrientation;
Add this to the openDriver(..) method:
setCameraDisplayOrientation(context, Camera.CameraInfo.CAMERA_FACING_BACK, theCamera);//this can be set after camera.setPreviewDisplay(); in api13+.
****Create this method****
Link: http://developer.android.com/reference/android/hardware/Camera.html
public static void setCameraDisplayOrientation(Context context,int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int degrees = 0;
switch (display.getRotation()) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
resultOrientation = (info.orientation + degrees) % 360;
resultOrientation = (360 - resultOrientation) % 360; // compensate the mirror
} else { // back-facing
resultOrientation = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(resultOrientation);
}
****Now modify getFramingRectInPreview()****
if(resultOrientation == 180 || resultOrientation == 0){//to work with landScape and reverse landScape
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;
}else{
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;
}
And modify this method public PlanarYUVLuminanceSource buildLuminanceSource(..)
if(resultOrientation == 180 || resultOrientation == 0){//TODO: This is to use camera in landScape mode
// 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);
}else{
byte[] rotatedData = new byte[data.length];
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;
return new PlanarYUVLuminanceSource(rotatedData, width, height, rect.left, rect.top, rect.width(), rect.height(), false);
}
You can use my fork of zxlib https://github.com/rusfearuth/zxing-lib-without-landscape-only. I disabled landscape mode only. You can set landscape/portrait and see correct camera view.
Adding camera.setDisplayOrientation(90); in CameraConfigurationManager.java worked for me.
for zxing 3.0, working lib https://github.com/xiaowei4895/zxing-android-portrait
for portrait mode
Thank you
I think the best library only solution is this one ...
https://github.com/SudarAbisheck/ZXing-Orient
You can include it in build.gradle as a dependency of your project in maven format ...
dependencies {
compile ''me.sudar:zxing-orient:2.1.1#aar''
}
Create AnyOrientationCaptureActivity and then override default CaptureActivity then it will work.
public void scanCode() {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setDesiredBarcodeFormats(CommonUtil.POSEIDON_CODE_TYPES);
integrator.setPrompt("Scan");
integrator.setCameraId(0);
integrator.setBeepEnabled(false);
integrator.setBarcodeImageEnabled(false);
integrator.setOrientationLocked(false);
//Override here
integrator.setCaptureActivity(AnyOrientationCaptureActivity.class);
integrator.initiateScan();
}
//create AnyOrientationCaptureActivity extend CaptureActivity
public class AnyOrientationCaptureActivity extends CaptureActivity {
}
Define in manifest
<activity
android:name=".views.AnyOrientationCaptureActivity"
android:screenOrientation="fullSensor"
android:stateNotNeeded="true"
android:theme="#style/zxing_CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden"></activity>
This is supposed to be a synched version to the above solution
https://github.com/zxing/zxing/tree/4b124b109d90ac2960078ce68e15a39885fc1b5b
Additionally to #roylee's modification I had to apply the following to the CameraConfigurationManager.java in order to get best possible preview and QR code recognition quality
diff --git a/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java b/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
index cd9d0d8..4f12c8c 100644
--- a/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
+++ b/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
## -56,21 +56,24 ## public final class CameraConfigurationManager {
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
+ // 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;
}
+ */
screenResolution = new Point(width, height);
Log.i(TAG, "Screen resolution: " + screenResolution);
- cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, false);
+ cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, true);//
Log.i(TAG, "Camera resolution: " + cameraResolution);
}
void setDesiredCameraParameters(Camera camera) {
+ camera.setDisplayOrientation(90);
Camera.Parameters parameters = camera.getParameters();
if (parameters == null) {
## -99,7 +102,7 ## public final class CameraConfigurationManager {
Point getScreenResolution() {
return screenResolution;
}
-
+
public void setFrontCamera(boolean newSetting) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_CAMERA, false);
## -109,12 +112,12 ## public final class CameraConfigurationManager {
editor.commit();
}
}
-
+
public boolean getFrontCamera() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(PreferencesActivity.KEY_FRONT_CAMERA, false);
}
-
+
public boolean getTorch() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
## -181,7 +184,14 ## public final class CameraConfigurationManager {
Camera.Size defaultSize = parameters.getPreviewSize();
bestSize = new Point(defaultSize.width, defaultSize.height);
}
+
+ // FIXME: test the bestSize == null case!
+ // swap width and height in portrait case back again
+ if (portrait) {
+ bestSize = new Point(bestSize.y, bestSize.x);
+ }
return bestSize;
+
}
private static String findSettableValue(Collection<String> supportedValues,
Related
i want to rotate image frame while video recording, i found one solution for rotate image byte array like below code.
private byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
// Rotate the Y luma
int i = 0;
for (int x = 0; x < imageWidth; x++) {
for (int y = imageHeight - 1; y >= 0; y--) {
yuv[i] = data[y * imageWidth + x];
i++;
}
}
// Rotate the U and V color components
i = imageWidth * imageHeight * 3 / 2 - 1;
for (int x = imageWidth - 1; x > 0; x = x - 2) {
for (int y = 0; y < imageHeight / 2; y++) {
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
i--;
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
i--;
}
}
return yuv;
}
this code return bad image like this
Please help me to rotate byte array image if any one have idea to achieve this.
Thank You.
I have found solution with NV12 method, this method through i have achieved proper output, if anyone facing same issue try below codes.
public byte[] rotateNV21(byte[] input, int width, int height, int rotation) {
byte[] output = new byte[input.length];
boolean swap = (rotation == 90 || rotation == 270);
// **EDIT:** in portrait mode & front cam this needs to be set to true:
boolean yflip = true;// (rotation == 90 || rotation == 180);
boolean xflip = (rotation == 270 || rotation == 180);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int xo = x, yo = y;
int w = width, h = height;
int xi = xo, yi = yo;
if (swap) {
xi = w * yo / h;
yi = h * xo / w;
}
if (yflip) {
yi = h - yi - 1;
}
if (xflip) {
xi = w - xi - 1;
}
output[w * yo + xo] = input[w * yi + xi];
int fs = w * h;
int qs = (fs >> 2);
xi = (xi >> 1);
yi = (yi >> 1);
xo = (xo >> 1);
yo = (yo >> 1);
w = (w >> 1);
h = (h >> 1);
// adjust for interleave here
int ui = fs + (w * yi + xi) * 2;
int uo = fs + (w * yo + xo) * 2;
// and here
int vi = ui + 1;
int vo = uo + 1;
output[uo] = input[ui];
output[vo] = input[vi];
}
}
return output;
}
I'm playing with the API2 Camera of Google and I'm having some problems with my code. I had two different CameraSessions, one for video and another one for images. To do it more efficient I change the code to use a unique Session and make the app more efficient.
After I did this, my camera preview is not working adequately. When I'm using a 4:3 aspect ratio my preview become stretched at height. In other way it looks fine when I'm using 16:9 ratio. In both cases my pictures looks fine, I mean, preview doesn't work correctly but the pictures that I took, have the correct aspect ratio.
I already check different post with the same problem:
Camera Preview Stretched on Few Android Devices
Camera display / preview in full screen does not maintain aspect ratio - image is skewed, stretched in order to fit on the screen
But the different answers didn't help me. I know that the problem is inside my onMeasure(), setTransformMatrix() or OnLayoutChangeListener() methods, but I don't know what I'm doing wrong.
Ignore the code about Rotation, right now it's dynamic. It always enter at else condition.
Here is my code:
private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.d(TAG, "[onLayoutChange] " + mCameraUI.getTextureView().getMeasuredWidth() + "x" + mCameraUI.getTextureView().getMeasuredHeight());
int width = right - left;
int height = bottom - top;
if (mPreviewWidth != width || mPreviewHeight != height
|| (mOrientationResize != mPrevOrientationResize)
|| mAspectRatioResize || mOrientationChanged) {
Log.i(TAG, "[onLayoutChange] Layout changed");
mPreviewWidth = width;
mPreviewHeight = height;
Log.i(TAG, "[onLayoutChange] Preview size: "+ mPreviewWidth + "x" + mPreviewHeight);
setTransformMatrix(width, height);
mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth,
(int) mSurfaceTextureUncroppedHeight);
mAspectRatioResize = false;
mOrientationChanged = true;
}
}
};
setTransform
private void setTransformMatrix(int width, int height) {
Log.i(TAG, "Screen: " + mPreviewWidth + "x" + mPreviewHeight);
mMatrix = new Matrix();
//mCameraUI.getTextureView().getTransform(mMatrix);
float scaleX = 1f, scaleY = 1f;
float scaledTextureWidth, scaledTextureHeight;
mAspectRatio= (float)height/(float)width;
if (mAspectRatio==(4f / 3f)){
scaledTextureWidth = Math.max(width,
(int) (height / mAspectRatio));
scaledTextureHeight = Math.max(height,
(int) (width * mAspectRatio));
Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 4:3=" + scaledTextureWidth + "x" + scaledTextureHeight );
}
else{
scaledTextureWidth = Math.max(width,
(int) (height / mAspectRatio));
scaledTextureHeight = Math.max(height,
(int) (width * mAspectRatio));
Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 16:9=" + scaledTextureWidth + "x" + scaledTextureHeight );
}
if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
Log.e(TAG,"mi SurfaceWidth = " + mSurfaceTextureUncroppedWidth + "and mi scaledWidth=" + scaledTextureWidth);
Log.e(TAG,"mi SurfaceHeigh = " + mSurfaceTextureUncroppedHeight + "and mi scaledHeight=" + scaledTextureHeight);
mSurfaceTextureUncroppedWidth = scaledTextureWidth;
mSurfaceTextureUncroppedHeight = scaledTextureHeight;
Log.e(TAG,"Surfaces: " + mSurfaceTextureUncroppedWidth + "x" + mSurfaceTextureUncroppedHeight);
if (mSurfaceTextureSizeListener != null) {
mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
(int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight);
}
}
scaleX = scaledTextureWidth / width;
scaleY = scaledTextureHeight / height;
mMatrix.setScale(scaleX, scaleY, scaledTextureWidth/2, scaledTextureHeight/2);
Log.e(TAG, "scale: X= " + scaleX + " Y=" + scaleY + "Width= " + scaledTextureWidth + "Height= " + scaledTextureHeight);
// init the position (this seems to be necessary too when the ratio is 16/9
mCameraUI.getTextureView().setX(0);
mCameraUI.getTextureView().setY(0);
// Translate the preview with the rotation is aspect ration is 4/3
if (mAspectRatio == 4f / 3f) {
Log.e(TAG, "aspect ratio standard");
float verticalTranslateOffset = (mCameraUI.getTextureView().getMeasuredHeight() - scaledTextureHeight) / 2;
float horizontalTranslateOffset = (mCameraUI.getTextureView().getMeasuredWidth() - scaledTextureWidth) / 2;
int rotation = CameraUtil.getDisplayRotation(mActivity);
switch (rotation) {
case 0:
// phone portrait; translate the preview up
mCameraUI.getTextureView().setY(-verticalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(-verticalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(-verticalTranslateOffset);
break;
case 90:
// phone landscape: translate the preview left
mCameraUI.getTextureView().setX(-horizontalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset);
break;
case 180:
// phone upside down: translate the preview bottom
mCameraUI.getTextureView().setY(verticalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(verticalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(verticalTranslateOffset);
break;
case 270:
// reverse landscape: translate the preview right
mCameraUI.getTextureView().setX(horizontalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(horizontalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(horizontalTranslateOffset);
break;
}
} else {
Log.e(TAG, "aspect ratio full");
mFaceView.setStandardPreviewTranslationOffset(0);
mFocusView.setStandardPreviewTranslationOffset(0);
}
mRenderOverlay.updateLayout();
mCameraUI.getTextureView().setTransform(mMatrix);
RectF previewRect = new RectF(0, 0, width, height);
mController.onPreviewRectChanged(CameraUtil.rectFToRect(previewRect));
}
onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
Log.d(TAG, "onMeasure PREVIOUS. Width x Height [" + widthMeasureSpec + " = " + width + "x" + heightMeasureSpec + " = " + height + "]");
int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
boolean isInHorizontal = Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation;
int newWidth;
int newHeight;
if (isInHorizontal) {
newHeight = getMeasuredHeight();
newWidth = (int) (newHeight * mAspectRatio);
} else {
newWidth = getMeasuredWidth();
newHeight = (int) (newWidth * mAspectRatio);
}
setMeasuredDimension(newWidth, newHeight);
Log.d(TAG, "onMeasure. Width x Height [" + newWidth + "x" + newHeight + "]");
}
Solved!
I had a default values for the BufferSize of my texture, which just are restarted when I inicializated a new Session or after change the after ratio. But the Width and Height values for the texture were not updated with the ratio, so it becomes streched again and again.
I solved it changing my defaultbufferSize with the PreviewSizes which I update always that i change the ratio.
public void createCameraPreviewSession(Size previewsize, Surface recordingSurface) {
try {
if (mCaptureSession != null) {
mCaptureSession.stopRepeating();
mCaptureSession.close();
mCaptureSession = null;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
List<Surface> surfaces = new ArrayList<Surface>();
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
;
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
.......
At the moment I have the code:
onPreviewFrame(byte[] data)
int[] rgbs = new int[480*800];
decodeYUV(rgbs, data, 480, 800);
Bitmap bitmap = Bitmap.createBitmap(rgbs, 800, 480, Bitmap.Config.ARGB_8888);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap,800,480,true);
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
sbut.setImageBitmap(rotatedBitmap);
where the decodeYUV function is found here
The preview is set up like this:
param.setPreviewSize(800, 480);
camera.setDisplayOrientation(90);
So the preview is set in portrait mode, Height = 800, Width = 480.
I end up having to go back to landscape to perform the conversion. And then rotate back to portrait again. I can imagine this is quite slow. Is there a more efficient alternative without a double rotation?
I would like to keep the preview in portrait mode. My end result should be that rotatedBitmap above, which is just portrait again. Any lines in the onPreviewFrame method can be changed.
In your case, I would 'freeze' the Activity in Potrait mode and use Gravity Sensor to check the rotations without Activity or Camera recreation.
to freeze use this:
this.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
to rotate I use this code:
public static void rotateNV21(byte[] input, byte[] output, int width, int height, int rotation) {
try{
boolean swap = (rotation == 90 || rotation == 270);
boolean yflip = (rotation == 90 || rotation == 180);
boolean xflip = (rotation == 270 || rotation == 180);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int xo = x, yo = y;
int w = width, h = height;
int xi = xo, yi = yo;
if (swap) {
xi = w * yo / h;
yi = h * xo / w;
}
if (yflip) {
yi = h - yi - 1;
}
if (xflip) {
xi = w - xi - 1;
}
output[w * yo + xo] = input[w * yi + xi];
int fs = w * h;
int qs = (fs >> 2);
xi = (xi >> 1);
yi = (yi >> 1);
xo = (xo >> 1);
yo = (yo >> 1);
w = (w >> 1);
h = (h >> 1);
// adjust for interleave here
int ui = fs + (w * yi + xi) * 2;
int uo = fs + (w * yo + xo) * 2;
// and here
int vi = ui + 1;
int vo = uo + 1;
output[uo] = input[ui];
output[vo] = input[vi];
}
}
}catch (IndexOutOfBoundsException e){
output = input;
}
}
I have already integrated zxing library in my application. Now i want that zxing camera will work on both mode landscape as well as on portrait mode. now it is working on one mode only. Can somebody help me out how to do this?
I used compyutech's answer, but there were some things missing. So, I'm putting everything required, here.
1. CameraConfigurationManager :
inside initFromCameraParameters method :
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
camera.setDisplayOrientation(90);
}
also remove this code from same method :
if (width < height) {
Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
int temp = width;
width = height;
height = temp;
}
2. CameraManager : class variables
private static final int MIN_FRAME_WIDTH = 340;
private static final int MIN_FRAME_HEIGHT = 240;
private static final int MAX_FRAME_WIDTH = 1200;
private static final int MAX_FRAME_HEIGHT = 675;
getFramingRect method :
public synchronized Rect getFramingRect() {
if (framingRect == null) {
if (camera == null) {
return null;
}
Point screenResolution = configManager.getScreenResolution();
if (screenResolution == null) {
// Called early, before init even finished
return null;
}
// Code added to enable portrait mode
int width = MIN_FRAME_WIDTH;
int height = MIN_FRAME_HEIGHT;
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
int tmp = 7 * screenResolution.x / 8;
width = (tmp) < MIN_FRAME_WIDTH ? MIN_FRAME_WIDTH : (tmp);
tmp = 1 * screenResolution.y / 3;
height = (tmp) < MIN_FRAME_WIDTH ? MIN_FRAME_WIDTH : ((tmp) > MAX_FRAME_HEIGHT ? MAX_FRAME_HEIGHT : (tmp));
Log.d(TAG, "Customized code for portrait mode in getFramingRect executed (Piyush Merja) ");
}else{
// Original Code
width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
}
// End
int leftOffset = (screenResolution.x - width) / 2;
int topOffset = (screenResolution.y - height) / 2;
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
Log.d(TAG, "Calculated framing rect: " + framingRect);
}
return framingRect;
}
private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
int dim = 5 * resolution / 8; // Target 5/8 of each dimension
if (dim < hardMin) {
return hardMin;
}
if (dim > hardMax) {
return hardMax;
}
return dim;
}
getFramingRectInPreview method :
public synchronized Rect getFramingRectInPreview() {
if (framingRectInPreview == null) {
Rect framingRect = getFramingRect();
if (framingRect == null) {
return null;
}
Rect rect = new Rect(framingRect);
Point cameraResolution = configManager.getCameraResolution();
Point screenResolution = configManager.getScreenResolution();
if (cameraResolution == null || screenResolution == null) {
// Called early, before init even finished
return null;
}
// Code added to enable portrait mode
if (context.getResources().getConfiguration().orientation == 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;
Log.d(TAG, "Customized code for portrait mode in getFramingRectInPreview executed (Piyush Merja) ");
}else{
// Original code commented
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;
}
// End
framingRectInPreview = rect;//this was missing in compyutech's answer
}
return framingRectInPreview;
}
3. DecodeHandler :
inside decode method :
long start = System.currentTimeMillis();
Result rawResult = null;
// Code added to enable portrait mode
if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
data = rotatedData;
int tmp = width;
width = height;
height = tmp;
Log.d(TAG, "Customized code for portrait mode in decode executed (Piyush Merja) ");
}//end
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
4. AndroidManifest.xml :
remove orientation settings for CaptureActivity.
Google this question.
I have used zxing zxing 2.3 and below solution worked for me.
1 In CameraConfigurationManager class, setDesiredCameraParameters Method add below code below pointed line
-> Camera.Parameters parameters = camera.getParameters();
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
camera.setDisplayOrientation(90);
}
2 In CameraManager class, getFramingRect Method replace code as below
int width = MIN_FRAME_WIDTH; int height = MIN_FRAME_HEIGHT;
if (context.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
int tmp = 7 * screenResolution.x / 8;
width = (tmp) < MIN_FRAME_WIDTH ? MIN_FRAME_WIDTH : (tmp);
tmp = 1 * screenResolution.y / 3;
height = (tmp) < MIN_FRAME_WIDTH ? MIN_FRAME_WIDTH : ((tmp) > MAX_FRAME_HEIGHT ? MAX_FRAME_HEIGHT : (tmp));
}else{
// Original Code
width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, > MAX_FRAME_WIDTH);
height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
}
3 In CameraManager class, getFramingRectInPreview Method replace code as below
if (context.getResources().getConfiguration().orientation ==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{
// Original code commented
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;
}
4 In DecodeHandler class, decode Method add below code below pointed line
-> Result rawResult = null;
if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
data = rotatedData;
int tmp = width;
width = height;
height = tmp;
}
Please find my working code
http://www.compyutech.co.in/repo/zxing-dynamic.zip
Hope this will help you....
I want to detect motion with Android sensors. For example I hold only bottom of phone and move top of phone to up. I think I need sampling algorithms. I can write a simple application to record data of sensors . For comparing real time data and recorded data ,Is there any libary ? I have suspicious about performace problems if I would make it. Is there a different path for detetion movements ?
These links will help you to start..
http://developer.android.com/guide/topics/sensors/sensors_motion.html
http://code.google.com/p/android-motion-detection/
http://www.helloandroid.com/tutorials/android-image-processing-detecting-motions
http://code.google.com/p/android-motion-detection/ is a good example.
I modified the isDifferent method in RgbMotionDetection class to detect the motion in the center part (25%) of the camera view.
protected static boolean isDifferent(int[] first, int width, int height) {
if (first==null) throw new NullPointerException();
if (mPrevious==null) return false;
if (first.length != mPrevious.length) return true;
if (mPreviousWidth != width || mPreviousHeight != height) return true;
int totDifferentPixels = 0;
int size = height * width;
int startHeight = height / 4;
int endHeight = 3 * (height / 4);
int startWidth = width / 4;
int endWidth = 3 * (width / 4);
int offSet = width / 4;
Log.d("params", "start height " + startHeight + "end height " + endHeight + "start width " + startWidth + "end width " + endWidth);
Boolean offSetApplied;
for (int i = startHeight, ij=0; i < endHeight; i++) {
{
offSetApplied = false;
for (int j = startWidth; j < endWidth; j++, ij++) {
if (!offSetApplied){
offSetApplied = true;
ij = startHeight * width + offSet;
}
int pix = (0xff & ((int)first[ij]));
int otherPix = (0xff & ((int)mPrevious[ij]));
//Catch any pixels that are out of range
if (pix < 0) pix = 0;
if (pix > 255) pix = 255;
if (otherPix < 0) otherPix = 0;
if (otherPix > 255) otherPix = 255;
if (Math.abs(pix - otherPix) >= mPixelThreshold) {
totDifferentPixels++;
//Paint different pixel red
//first[ij] = Color.RED;
}
}
}
}
if (totDifferentPixels <= 0) totDifferentPixels = 1;
//boolean different = totDifferentPixels > mThreshold;
int percent = 100/(size/totDifferentPixels);
//float percent = (float) totDifferentPixels / (float) size;
boolean different = percent > SENSITIVITY;
String output = "Number of different pixels: " + totDifferentPixels + "> " + percent + "%";
if (different) {
Log.e(TAG, output);
} else {
Log.d(TAG, output);
}
return different;
}