I'm working on an Android app that shows a camera preview. Ideally I'd like the app to work in portrait mode, which means I need to deal with rotation of the camera preview image.
I only need to support API level 8 (Android version 2.2) and up, so I can use Camera.setDisplayOrientation to set the orientation, and the API docs for that method include a setDisplayOrientation function that does what I want. The only problem is that it uses the API Level 9 Camera.CameraInfo to get the orientation of the camera with respect to the device (presumably to deal with landscape vs portrait devices).
So is it safe to assume that I can do setDisplayOrientation(90) for all level 8 devices and just use CameraInfo.orientation for newer devices?
I have tried the following on an HTC Evo Shift with a project set to API8 (worked great):
Configuration cfg = mContext.getResources().getConfiguration();
if (cfg.orientation == Configuration.ORIENTATION_PORTRAIT) {
mCamera.setDisplayOrientation(90);
}
As a follow up for anyone else finding this - I didn't find a definitive answer on this, so I did as I suggested above (setDisplayOrientation(90)) for 2.2 devices and released the app. It's had about 70,000 downloads and no reports of the camera display being wrongly rotated by 90 degrees, so it looks like this is a reasonable solution.
I'm posting the link to Android's developers help in the Camera matter:
http://developer.android.com/guide/topics/media/camera.html
About your question in specific, i took a look at the API and i guess, since the surfaceChanged method is called every time a change in surface is made and the equipment have only 2 position, you are probably right, since u implement the corrected methods in the surfaceChanged method. Try to implement it and if you can't get it to work post the problem and i'll try to help more.
Related
In my AS3 Flex Mobile application for Android, I am using camera and it is being automatically rotated 90 degrees before I even done any video rotation by myself, it seems like it's a known bug in AIR. But I was wondering if anyone found a solution since it's really pretty important feature for mobile application developer.
I've tried to do some rotation manually in my code, but it is only fixes the view on my display, but still sends the wrong video to the receiver.
If any code is required I will add the snippets
Please let me know.
As you mentioned, this is a known bug with AIR. It is not consistent, either. On some devices, it is in the correct orientation but in some (and all iOS devices, I believe, though I haven't fully tested that), it is rotated as you are seeing. For example, it was always oriented correctly on my Nexus 4 and on my Nexus 5, but a friends Moto X is rotated incorrectly.
Unfortunately, I don't believe there is anything you can do short of having the user do a calibration (i.e. overlay a straight line and tell them to place it horizontally and click a button) and rotating the camera display and any images you take with the display.
That being said, if you are using the camera to take photos, I highly recommend using CameraUI instead, which is the native implementation.
I've faced the same issue today but i'm developping in Java, not with AIR so i don't know if it the same, for me the solution was to add this line before starting the recording.
mMediaRecorder.setOrientationHint(90);
I'm building a custom camera application for Android. The Camera.Parameters API contains methods like setPreviewSize or setPictureSize, that are working well.
But I am trying to use setJpegQuality(int) parameter:
Camera cam = getCameraInstance();
if(cam == null){
setResult(INSTANCE_ERROR);
finish();
}
params = cam.getParameters();
params.setJpegQuality(jpegQuality);
cam.setParameters(params);
I am testing my application on 3 different devices : an HTC Desire Z, a Galaxy S2 and a Galaxy S4.
setJpegQuality is working on HTC (Android 2.2.1) and on Galaxy S2 (4.1.2), but fails on Galaxy S4 device (4.2.2).
So my question : Is this function deprecated ? Is there another way to set picture quality ? On the Developer documentation it doesnt seems to be a deprecated function so i am a little confused...
I also tried
params.set("jpeg-quality", jpegQuality);
But its the same :(
Thanks for the answers.
For S3 and S4, you can write device specific code to reduce the size of file.
If you search on google, Android dev team also mentioned that it all depends on the implementation by the manufacturer(https://code.google.com/p/android/issues/detail?id=8091). The implementation of the camera parameters and function totally depends on the hardware used I think.
I had used motion sensors for one of my apps. There also, I had to write device specific code, to get the required behaviour in the app.
I know its not what we expect as a developer, but i believe we, developers, can fix anything. :)
I use the CWAC-Camera library for my custom camera. I forked the main repository and added a jpegQuality parameter to the PictureTransaction:
https://github.com/cookbrite/cwac-camera/commit/65a0a2082194dfc8069f605f0191c43357bb0852
This ensures that the resulting picture is always compressed to the required quality.
One drawback with this approach is that it has to load and compress the full size image file in application code, whereas using setJpegQuality on the Camera.Parameters may be more optimized.
Sorry I didnt see answers finaly come :) I dont even use this not working parameters anymore
I found a solution to set the quality of my picture, when i save it as file :
FileOutputStream fos = new FileOutputStream(finalFilePath);
bmp.compress(Bitmap.CompressFormat.JPEG, jpegQuality, fos);
Hope it helps
I was looking for a method to use the camera on android devices without a surfaceview or a preview. I found out that, it is impossible to take picture without that preview. However, I have found a tutorial which is actually working taking pictures without a preview. Here is the link: http://www.vogella.com/articles/AndroidCamera/article.html
After switching the camera in the code from front to back-facing the app didn't crashed but it gave me an error 100. So it is only working with the front cam at the moment.
I am using a Samsung Galaxy S3(4.1.2) and i will test it on a Galaxy S2 and a Galaxy S3 Mini.
Anyone a good explanation for this?
You cannot take a picture without starting preview.
While some Android devices are more flexible, and allow takePicture to be called without preview running, this is technically against the API specifications.
It won't work on a large number of devices, so please don't rely on it. That tutorial is wrong, and presumably tested only on one of the devices that allows this behavior.
If you don't want a visible preview, see this question for ways to do that in Android versions >= 3.0.
Actually the time interval of question and answer is large, but may help others.
You can try this library to take picture even from service:
https://github.com/kevalpatel2106/android-hidden-camera
It uses a feature to draw over other apps and create a fake surface. Hope it helps.
First of all, I would like to refer to this Issue on the google groups.
My problem is i want the landscape-native app to work in portrait mode. The way of getting the app into portrait mode is no problem at all, but when you display the app in portrait mode, my problem occurs.
When the Barcode Scanner is starting op, its camera view is (pr. default) at a +90 degree angle. When viewing the app in portrait mode the Barcode Scanner is (naturally) still at a +90 degree angle.
In the referred Issue-page there is displayed a hack to get around the problem, but this does not seem to work on most devices. This does also not work on my targeted devices.
I would like to hear if some of you have got a work around, or found the place in the source where you can 'undo' the 90 degree flipping?
A usable answer will be utmost appriciated :D Unfortunately i can't make progress in the project before this is solved. It is demanded to run in portrait mode ;)
In advance ... Thanks :)
I have implemented this in a private build. It is complicated and I can't share the details. The key steps are:
Call Camera.setDisplayOrientation() to counteract the rotation; see the Android javadoc for some discussion on that
Make sure that Camera.Parameters.setPreviewSize() is called correctly; preview sizes are reported in landscape but need to be set in portrait
(And guess what -- the default orientation of phones is considered portrait but tablets is considered landscape! Make sure you've accounted for that too.)
Finally, the preview data is always in landscape mode. You need to rotate it yourself to read it right-side-up, or otherwise account for that.
I'm using this camera code to ask the camera to rotate the captured image data:
Camera.Parameters params = camera.getParameters();
params.set("rotation", 90);
camera.setParameters(params);
this seems to work on all phones, except the Droid. Has anyone else seen this? The image data is always landscape, however, the native camera app on the Droid produces portrait images ok.
I wonder if the Droid will only respect the new Camera.Parameters.setRotation() method, but this seems to only be available in API level 5?
setRotation also didn't seem to work for me on Nexus One, but I did get image rotation to work by following the example of the android Camera app itself.
The source code is available here:
https://android.googlesource.com/platform/packages/apps/Camera
Start with the Camera.java, but you'll also be looking at ImageManager.java, Util.java, and other files.
The basic idea is, you listen for orientation changes and capture what the orientation is at the time you snapped the picture. Then, when you get the picture bytes in the callback, you manipulate the bitmap, doing a rotation on the bitmap. Then convert the rotated bitmap back to jpeg. When you are done, you'll have had to copy a shocking amount of code from the camera app just for this rotation.
The rotation may just be stored in the jpeg exif header as explained in the setRotation document. On Droid that is actually the case. You can use jpeg header reading tools like jhead to verify this. You can also use the ExifInterface API to read the orientation tag in your program.
The Droid runs Android 2.0 (well, now 2.0.1) which are API levels 5 and 6, respectively.
So it's quite possible that the Droid only respects the (more sensible) 2.0+ API for rotation.
However, I guess your concern is compatibility across a range of device types and OS versions, so I imagine you would have to invoke the 2.0+ API via reflection after detecting the OS version (using android.os.Build.VERSION_CODES).